小工具整理

This commit is contained in:
Abin
2025-07-31 16:05:55 +08:00
commit 1011eb44e1
566 changed files with 267142 additions and 0 deletions
View File
+2
View File
@@ -0,0 +1,2 @@
# Tools
个人自用小工具收藏
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.
+950
View File
@@ -0,0 +1,950 @@
#target photoshop
app.bringToFront();
// This script exports Adobe Photoshop layers as individual PNGs. It also
// writes a JSON file which can be imported into Spine where the images
// will be displayed in the same positions and draw order.
// Copyright (c) 2012-2017, Esoteric Software
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
// * Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
var scriptVersion = 2.9; // This is incremented every time the script is modified, so you know if you have the latest.
var cs2 = parseInt(app.version) < 10;
var originalDoc;
try {
originalDoc = app.activeDocument;
} catch (ignored) {}
var defaultSettings = {
ignoreHiddenLayers: false,
ignoreBackground: true,
writeTemplate: false,
writeJson: true,
trimWhitespace: true,
scale: 1,
padding: 1,
imagesDir: "./images/",
jsonPath: "./",
};
var settings = loadSettings();
showSettingsDialog();
var progress, cancel;
function run () {
showProgressDialog();
// Output dirs.
var jsonFile = new File(jsonPath(settings.jsonPath));
jsonFile.parent.create();
var imagesDir = absolutePath(settings.imagesDir);
var imagesFolder = new Folder(imagesDir);
imagesFolder.create();
// Get ruler origin.
var action = new ActionReference();
action.putEnumerated(cID("Dcmn"), cID("Ordn"), cID("Trgt"));
var result = executeActionGet(action);
var xOffSet = result.getInteger(sID("rulerOriginH")) >> 16;
var yOffSet = result.getInteger(sID("rulerOriginV")) >> 16;
activeDocument.duplicate();
deselectLayers();
try {
convertToRGB();
} catch (ignored) {}
if (app.activeDocument.mode != DocumentMode.RGB) {
alert("Please change the image mode to RGB color.");
return;
}
// Output template image.
if (settings.writeTemplate) {
if (settings.scale != 1) {
storeHistory();
scaleImage();
}
var file = new File(imagesDir + "template.png");
if (file.exists) file.remove();
savePNG(file);
if (settings.scale != 1) restoreHistory();
}
if (!settings.jsonPath && !settings.imagesDir) {
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
return;
}
// Rasterize all layers.
try {
executeAction(sID("rasterizeAll"), undefined, DialogModes.NO);
} catch (ignored) {}
// Add a history item to prevent layer visibility from changing by the active layer being reset to the top.
activeDocument.artLayers.add();
// Collect and hide layers.
var layers = [];
collectLayers(activeDocument, layers);
var layersCount = layers.length;
// Add a history item to prevent layer visibility from changing by restoreHistory.
activeDocument.artLayers.add();
// Store the bones, slot names, and layers for each skin.
var bones = { root: { name: "root", x: 0, y: 0, children: [] } };
var slots = {}, slotsCount = 0;
var skins = { "default": [] }, skinsCount = 0;
var totalLayerCount = 0;
outer:
for (var i = 0; i < layersCount; i++) {
var layer = layers[i];
if (layer.kind != LayerKind.NORMAL && !isGroup(layer)) continue;
layer.attachmentName = folders(layer, "") + stripTags(layer.name);
var bone = null;
var boneLayer = findTagLayer(layer, "bone", null);
if (boneLayer) {
function getParentBone (boneLayer, bones) {
var parentName = findTag(boneLayer.parent, "bone", "root");
var parent = bones[parentName];
if (!parent) { // Parent bone group with no attachment layers.
var parentParent = getParentBone(boneLayer.parent, bones);
bones[parentName] = parent = { name: parentName, parent: parentParent, children: [], x: 0, y: 0 };
parentParent.children.push(parent);
}
return parent;
}
var parent = getParentBone(boneLayer, bones);
var boneName = stripTags(boneLayer.name);
bone = bones[boneName];
if (bone) {
if (parent != bone.parent) {
alert("Multiple layers for the \"" + boneName + "\" bone have different parent bones:\n\n"
+ bone.parent.name + "\n"
+ parent.name);
return;
}
} else {
bones[boneName] = bone = { name: boneName, parent: parent, children: [] };
parent.children.push(bone);
}
if (layer.wasVisible) {
bone.x = (layer.bounds[0].as("px")) * settings.scale - settings.padding;
bone.x += (layer.bounds[2].as("px") - layer.bounds[0].as("px")) * settings.scale / 2 + settings.padding;
bone.y = (activeDocument.height.as("px") - layer.bounds[1].as("px")) * settings.scale + settings.padding;
bone.y -= (layer.bounds[3].as("px") - layer.bounds[1].as("px")) * settings.scale / 2 + settings.padding;
// Make relative to the Photoshop document ruler origin.
bone.x -= xOffSet * settings.scale;
bone.y -= (activeDocument.height.as("px") - yOffSet) * settings.scale;
}
}
layer.slotName = findTag(layer, "slot", layer.attachmentName);
if (!slots[layer.slotName]) slotsCount++;
slots[layer.slotName] = { bone: bone, attachment: layer.wasVisible ? layer.attachmentName : null };
if (layer.blendMode == BlendMode.LINEARDODGE)
slots[layer.slotName].blend = "additive";
else if (layer.blendMode == BlendMode.MULTIPLY)
slots[layer.slotName].blend = "multiply";
else if (layer.blendMode == BlendMode.SCREEN)
slots[layer.slotName].blend = "screen";
var skinName = findTag(layer, "skin", "default");
var skinSlots = skins[skinName];
if (!skinSlots) {
skins[skinName] = skinSlots = {};
skinsCount++;
}
var skinLayers = skinSlots[layer.slotName];
if (!skinLayers) skinSlots[layer.slotName] = skinLayers = [];
for (var ii = 0, nn = skinLayers.length; ii < nn; ii++) {
if (skinLayers[ii].attachmentName == layer.attachmentName) {
alert("Multiple layers for the \"" + skinName + "\" skin have the same name:\n\n"
+ layer.attachmentName
+ "\n\nRename or use the [ignore] tag for the other layers.");
return;
}
}
skinLayers[skinLayers.length] = layer;
totalLayerCount++;
}
// Output skeleton.
var json = '{ "skeleton": { "images": "' + imagesDir + '" },\n"bones": [\n';
// Output bones.
function outputBone (bone) {
var json = bone.parent ? ",\n" : "";
json += '\t{ "name": ' + quote(bone.name);
var x = bone.x, y = bone.y;
if (bone.parent) {
x -= bone.parent.x;
y -= bone.parent.y;
json += ', "parent": ' + quote(bone.parent.name);
}
if (x) json += ', "x": ' + x;
if (y) json += ', "y": ' + y;
json += ' }';
for (var i = 0, n = bone.children.length; i < n; i++)
json += outputBone(bone.children[i]);
return json;
}
for (var boneName in bones) {
if (!bones.hasOwnProperty(boneName)) continue;
var bone = bones[boneName];
if (!bone.parent) json += outputBone(bone);
}
json += '\n],\n"slots": [\n';
// Output slots.
var slotIndex = 0;
for (var slotName in slots) {
if (!slots.hasOwnProperty(slotName)) continue;
var slot = slots[slotName];
json += '\t{ "name": ' + quote(slotName) + ', "bone": ' + quote(slot.bone ? slot.bone.name : "root");
if (slot.attachment) json += ', "attachment": ' + quote(slot.attachment);
if (slot.blend) json += ', "blend": ' + quote(slot.blend);
json += ' }';
slotIndex++;
json += slotIndex < slotsCount ? ",\n" : "\n";
}
json += '],\n"skins": {\n';
// Output skins.
var skinIndex = 0, layerCount = 0;
for (var skinName in skins) {
if (!skins.hasOwnProperty(skinName)) continue;
json += '\t"' + skinName + '": {\n';
var skinSlots = skins[skinName];
var skinSlotIndex = 0, skinSlotsCount = countAssocArray(skinSlots);
for (var slotName in skinSlots) {
if (!skinSlots.hasOwnProperty(slotName)) continue;
var bone = slots[slotName].bone;
json += '\t\t' + quote(slotName) + ': {\n';
var skinLayers = skinSlots[slotName];
var skinLayerIndex = 0, skinLayersCount = skinLayers.length;
for (var i = skinLayersCount - 1; i >= 0; i--) {
var layer = skinLayers[i];
layer.visible = true;
if (cancel) {
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
return;
}
setProgress(++layerCount / totalLayerCount, trim(layer.name));
var placeholderName = layer.attachmentName;
var attachmentName = (skinName == "default" ? "" : skinName + "/") + placeholderName;
if (isGroup(layer)) {
activeDocument.activeLayer = layer;
layer = layer.merge();
}
storeHistory();
var x = activeDocument.width.as("px") * settings.scale;
var y = activeDocument.height.as("px") * settings.scale;
if (settings.trimWhitespace) {
if (!layer.isBackgroundLayer) activeDocument.trim(TrimType.TRANSPARENT, false, true, true, false);
x -= activeDocument.width.as("px") * settings.scale;
y -= activeDocument.height.as("px") * settings.scale;
if (!layer.isBackgroundLayer) activeDocument.trim(TrimType.TRANSPARENT, true, false, false, true);
}
var width = activeDocument.width.as("px") * settings.scale + settings.padding * 2;
var height = activeDocument.height.as("px") * settings.scale + settings.padding * 2;
// Save image.
if (settings.imagesDir) {
if (settings.scale != 1) scaleImage();
if (settings.padding > 0) activeDocument.resizeCanvas(width, height, AnchorPosition.MIDDLECENTER);
var file = new File(imagesDir + attachmentName);
file.parent.create();
savePNG(file);
}
restoreHistory();
if (layerCount < totalLayerCount) deleteLayer(layer);
x += Math.round(width) / 2 - settings.padding;
y += Math.round(height) / 2 - settings.padding;
// Make relative to the Photoshop document ruler origin.
x -= xOffSet * settings.scale;
y -= (activeDocument.height.as("px") - yOffSet) * settings.scale;
if (bone) { // Make relative to parent bone.
x -= bone.x;
y -= bone.y;
}
json += "\t\t\t" + quote(placeholderName) + ': { ';
if (attachmentName != placeholderName) json += '"name": ' + quote(attachmentName) + ', ';
json += '"x": ' + x + ', "y": ' + y + ', "width": ' + Math.round(width) + ', "height": ' + Math.round(height);
json += " }" + (++skinLayerIndex < skinLayersCount ? ",\n" : "\n");
}
json += "\t\t}" + (++skinSlotIndex < skinSlotsCount ? ",\n" : "\n");
}
json += "\t\}" + (++skinIndex < skinsCount ? ",\n" : "\n");
}
json += '},\n"animations": { "animation": {} }\n}';
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
// Output JSON file.
if (settings.writeJson && settings.jsonPath) {
jsonFile.encoding = "UTF-8";
jsonFile.remove();
jsonFile.open("w", "TEXT");
jsonFile.lineFeed = "\n";
jsonFile.write(json);
jsonFile.close();
}
}
// Settings dialog:
function showSettingsDialog () {
if (parseInt(app.version) < 9) {
alert("Photoshop CS2 or later is required.");
return;
}
if (!originalDoc) {
alert("Please open a document before running the PhotoshopToSpine script.");
return;
}
if (!hasFilePath()) {
alert("Please save the document before running the PhotoshopToSpine script.");
return;
}
// Layout.
var dialog = new Window("dialog", "PhotoshopToSpine v" + scriptVersion), group;
dialog.alignChildren = "fill";
try {
dialog.add("image", undefined, new File(scriptDir() + "logo.png"));
} catch (ignored) {}
var settingsGroup = dialog.add("panel", undefined, "Settings");
settingsGroup.margins = [10,15,10,10];
settingsGroup.alignChildren = "fill";
var checkboxGroup = settingsGroup.add("group");
checkboxGroup.alignChildren = ["left", ""];
checkboxGroup.orientation = "row";
group = checkboxGroup.add("group");
group.orientation = "column";
group.alignChildren = ["left", ""];
var ignoreHiddenLayersCheckbox = group.add("checkbox", undefined, " Ignore hidden layers");
ignoreHiddenLayersCheckbox.value = settings.ignoreHiddenLayers;
var ignoreBackgroundCheckbox = group.add("checkbox", undefined, " Ignore background layer");
ignoreBackgroundCheckbox.value = settings.ignoreBackground;
var trimWhitespaceCheckbox = group.add("checkbox", undefined, " Trim whitespace");
trimWhitespaceCheckbox.value = settings.trimWhitespace;
group = checkboxGroup.add("group");
group.orientation = "column";
group.alignChildren = ["left", ""];
group.alignment = ["", "top"];
var writeJsonCheckbox = group.add("checkbox", undefined, " Write Spine JSON");
writeJsonCheckbox.value = settings.writeJson;
var writeTemplateCheckbox = group.add("checkbox", undefined, " Write template image");
writeTemplateCheckbox.value = settings.writeTemplate;
var scaleText, paddingText, scaleSlider, paddingSlider;
if (!cs2) {
var slidersGroup = settingsGroup.add("group");
group = slidersGroup.add("group");
group.orientation = "column";
group.alignChildren = ["right", ""];
group.add("statictext", undefined, "Scale:");
group.add("statictext", undefined, "Padding:");
group = slidersGroup.add("group");
group.orientation = "column";
scaleText = group.add("edittext", undefined, settings.scale * 100);
scaleText.characters = 4;
paddingText = group.add("edittext", undefined, settings.padding);
paddingText.characters = 4;
group = slidersGroup.add("group");
group.orientation = "column";
group.add("statictext", undefined, "%");
group.add("statictext", undefined, "px");
group = slidersGroup.add("group");
group.orientation = "column";
group.alignChildren = ["fill", ""];
group.alignment = ["fill", ""];
scaleSlider = group.add("slider", undefined, settings.scale * 100, 1, 100);
paddingSlider = group.add("slider", undefined, settings.padding, 0, 4);
} else {
group = settingsGroup.add("group");
group.add("statictext", undefined, "Scale:");
scaleText = group.add("edittext", undefined, settings.scale * 100);
scaleText.preferredSize.width = 50;
scaleSlider = settingsGroup.add("slider", undefined, settings.scale * 100, 1, 100);
group = settingsGroup.add("group");
group.add("statictext", undefined, "Padding:");
paddingText = group.add("edittext", undefined, settings.padding);
paddingText.preferredSize.width = 50;
paddingSlider = settingsGroup.add("slider", undefined, settings.padding, 0, 4);
}
var outputPathGroup = dialog.add("panel", undefined, "Output Paths");
outputPathGroup.alignChildren = ["fill", ""];
outputPathGroup.margins = [10,15,10,10];
var imagesDirText, imagesDirPreview, jsonPathText, jsonPathPreview;
if (!cs2) {
var textGroup = outputPathGroup.add("group");
textGroup.orientation = "column";
textGroup.alignChildren = ["fill", ""];
group = textGroup.add("group");
group.add("statictext", undefined, "Images:");
imagesDirText = group.add("edittext", undefined, settings.imagesDir);
imagesDirText.alignment = ["fill", ""];
imagesDirPreview = textGroup.add("statictext", undefined, "");
imagesDirPreview.maximumSize.width = 260;
group = textGroup.add("group");
var jsonLabel = group.add("statictext", undefined, "JSON:");
jsonLabel.justify = "right";
jsonLabel.minimumSize.width = 41;
jsonPathText = group.add("edittext", undefined, settings.jsonPath);
jsonPathText.alignment = ["fill", ""];
jsonPathPreview = textGroup.add("statictext", undefined, "");
jsonPathPreview.maximumSize.width = 260;
} else {
outputPathGroup.add("statictext", undefined, "Images:");
imagesDirText = outputPathGroup.add("edittext", undefined, settings.imagesDir);
imagesDirText.alignment = "fill";
outputPathGroup.add("statictext", undefined, "JSON:");
jsonPathText = outputPathGroup.add("edittext", undefined, settings.jsonPath);
jsonPathText.alignment = "fill";
}
var buttonGroup = dialog.add("group");
var helpButton;
if (!cs2) helpButton = buttonGroup.add("button", undefined, "Help");
group = buttonGroup.add("group");
group.alignment = ["fill", ""];
group.alignChildren = ["right", ""];
var runButton = group.add("button", undefined, "OK");
var cancelButton = group.add("button", undefined, "Cancel");
// Tooltips.
writeTemplateCheckbox.helpTip = "When checked, a PNG is written for the currently visible layers.";
writeJsonCheckbox.helpTip = "When checked, a Spine JSON file is written.";
trimWhitespaceCheckbox.helpTip = "When checked, blank pixels aroind the edges of each image are removed.";
scaleSlider.helpTip = "Scales the PNG files. Useful when using higher resolution art in Photoshop than in Spine.";
paddingSlider.helpTip = "Blank pixels around the edge of each image. Can avoid aliasing artifacts for opaque pixels along the image edge.";
imagesDirText.helpTip = "The folder to write PNGs. Begin with \"./\" to be relative to the PSD file. Blank to disable writing PNGs.";
jsonPathText.helpTip = "Output JSON file if ending with \".json\", else the folder to write the JSON file. Begin with \"./\" to be relative to the PSD file. Blank to disable writing a JSON file.";
// Events.
scaleText.onChanging = function () { scaleSlider.value = scaleText.text; };
scaleSlider.onChanging = function () { scaleText.text = Math.round(scaleSlider.value); };
paddingText.onChanging = function () { paddingSlider.value = paddingText.text; };
paddingSlider.onChanging = function () { paddingText.text = Math.round(paddingSlider.value); };
cancelButton.onClick = function () {
cancel = true;
dialog.close();
return;
};
if (!cs2) helpButton.onClick = showHelpDialog;
jsonPathText.onChanging = function () {
var text = jsonPathText.text ? jsonPath(jsonPathText.text) : "<no JSON output>";
if (!cs2) {
jsonPathPreview.text = text;
jsonPathPreview.helpTip = text;
} else
jsonPathText.helpTip = text;
};
imagesDirText.onChanging = function () {
var text = imagesDirText.text ? absolutePath(imagesDirText.text) : "<no image output>";
if (!cs2) {
imagesDirPreview.text = text;
imagesDirPreview.helpTip = text;
} else
imagesDirText.helpTip = text;
};
// Run now.
jsonPathText.onChanging();
imagesDirText.onChanging();
function updateSettings () {
settings.ignoreHiddenLayers = ignoreHiddenLayersCheckbox.value;
settings.ignoreBackground = ignoreBackgroundCheckbox.value;
settings.writeTemplate = writeTemplateCheckbox.value;
settings.writeJson = writeJsonCheckbox.value;
settings.trimWhitespace = trimWhitespaceCheckbox.value;
var scaleValue = parseFloat(scaleText.text);
if (scaleValue > 0 && scaleValue <= 100) settings.scale = scaleValue / 100;
settings.imagesDir = imagesDirText.text;
settings.jsonPath = jsonPathText.text;
var paddingValue = parseInt(paddingText.text);
if (paddingValue >= 0) settings.padding = paddingValue;
}
runButton.onClick = function () {
if (scaleText.text <= 0 || scaleText.text > 100) {
alert("Scale must be between > 0 and <= 100.");
return;
}
if (paddingText.text < 0) {
alert("Padding must be >= 0.");
return;
}
updateSettings();
saveSettings();
ignoreHiddenLayersCheckbox.enabled = false;
ignoreBackgroundCheckbox.enabled = false;
writeTemplateCheckbox.enabled = false;
writeJsonCheckbox.enabled = false;
trimWhitespaceCheckbox.enabled = false;
scaleText.enabled = false;
scaleSlider.enabled = false;
paddingText.enabled = false;
paddingSlider.enabled = false;
imagesDirText.enabled = false;
jsonPathText.enabled = false;
if (!cs2) helpButton.enabled = false;
runButton.enabled = false;
cancelButton.enabled = false;
var rulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
try {
// var start = new Date().getTime();
run();
// alert(new Date().getTime() - start);
} catch (e) {
alert("An unexpected error has occurred.\n\nTo debug, run the PhotoshopToSpine script using Adobe ExtendScript "
+ "with \"Debug > Do not break on guarded exceptions\" unchecked.");
debugger;
} finally {
if (activeDocument != originalDoc) activeDocument.close(SaveOptions.DONOTSAVECHANGES);
app.preferences.rulerUnits = rulerUnits;
dialog.close();
}
};
dialog.center();
dialog.show();
}
function loadSettings () {
var options = null;
try {
options = app.getCustomOptions(sID("settings"));
} catch (e) {
}
var settings = {};
for (var key in defaultSettings) {
if (!defaultSettings.hasOwnProperty(key)) continue;
var typeID = sID(key);
if (options && options.hasKey(typeID))
settings[key] = options["get" + getOptionType(defaultSettings[key])](typeID);
else
settings[key] = defaultSettings[key];
}
return settings;
}
function saveSettings () {
if (cs2) return; // No putCustomOptions.
var action = new ActionDescriptor();
for (var key in defaultSettings) {
if (!defaultSettings.hasOwnProperty(key)) continue;
action["put" + getOptionType(defaultSettings[key])](sID(key), settings[key]);
}
app.putCustomOptions(sID("settings"), action, true);
}
function getOptionType (value) {
switch (typeof(value)) {
case "boolean": return "Boolean";
case "string": return "String";
case "number": return "Double";
};
throw new Error("Invalid default setting: " + value);
}
// Help dialog.
function showHelpDialog () {
var dialog = new Window("dialog", "PhotoshopToSpine - Help");
dialog.alignChildren = ["fill", ""];
dialog.orientation = "column";
dialog.alignment = ["", "top"];
var helpText = dialog.add("statictext", undefined, ""
+ "This script writes layers as images and creates a JSON file to bring the images into Spine in the same positions and draw order as they had in Photoshop.\n"
+ "\n"
+ "The ruler origin corresponds to 0,0 in Spine.\n"
+ "\n"
+ "Tags in square brackets can be used in layer and group names to customize the output.\n"
+ "\n"
+ "Group names:\n"
+ "• [bone] Slot and bone layers in the group are placed under a bone, named after the group. The bone is created at the center of a visible attachment.\n"
+ "• [slot] Layers in the group are placed in a slot, named after the group.\n"
+ "• [skin] Layers in the group are placed in a skin, named after the group. Skin images are output in a subfolder for the skin.\n"
+ "• [merge] Layers in the group are merged and a single image is output, named after the group.\n"
+ "• [folder] Layers in the group will be output in a subfolder. Folder groups can be nested.\n"
+ "• [ignore] Layers in the group and any child groups will not be output.\n"
+ "\n"
+ "Layer names:\n"
+ "• [ignore] The layer will not be output."
, {multiline: true});
helpText.preferredSize.width = 325;
var closeButton = dialog.add("button", undefined, "Close");
closeButton.alignment = ["center", ""];
closeButton.onClick = function () {
dialog.close();
};
dialog.center();
dialog.show();
}
// Progress dialog:
function showProgressDialog () {
var dialog = new Window("palette", "PhotoshopToSpine - Processing...");
dialog.alignChildren = "fill";
dialog.orientation = "column";
var message = dialog.add("statictext", undefined, "Initializing...");
var group = dialog.add("group");
var bar = group.add("progressbar");
bar.preferredSize = [300, 16];
bar.maxvalue = 10000;
var cancelButton = group.add("button", undefined, "Cancel");
cancelButton.onClick = function () {
cancel = true;
cancelButton.enabled = false;
return;
};
dialog.center();
dialog.show();
dialog.active = true;
progress = {
dialog: dialog,
bar: bar,
message: message
};
}
function setProgress (percent, layerName) {
progress.bar.value = 10000 * percent;
progress.message.text = "Layer: " + layerName;
if (!progress.dialog.active) progress.dialog.active = true;
}
// PhotoshopToSpine utility:
function unlock (layer) {
if (layer.allLocked) layer.allLocked = false;
if (!layer.layers) return;
for (var i = layer.layers.length - 1; i >= 0; i--)
unlock(layer.layers[i]);
}
function deleteLayer (layer) {
unlock(layer);
activeDocument.activeLayer = activeDocument.artLayers[0];
layer.remove();
}
function collectLayers (parent, collect) {
for (var i = parent.layers.length - 1; i >= 0; i--) {
if (cancel) return;
var layer = parent.layers[i];
if (settings.ignoreHiddenLayers && !layer.visible) {
deleteLayer(layer);
continue;
}
if (settings.ignoreBackground && layer.isBackgroundLayer) {
deleteLayer(layer);
continue;
}
if (findTag(layer, "ignore")) {
deleteLayer(layer);
continue;
}
var group = isGroup(layer);
if (!group && layer.bounds[2] == 0 && layer.bounds[3] == 0) {
deleteLayer(layer);
continue;
}
// Ensure tags are valid.
var re = /\[([^\]]+)\]/g;
while (true) {
var matches = re.exec(layer.name);
if (!matches) break;
var tag = matches[1].toLowerCase();
if (group) {
if (!isValidGroupTag(tag)) {
var message = "Invalid group name:\n\n" + layer.name;
if (isValidLayerTag(tag))
message += "\n\nThe [" + tag + "] tag is only valid for layers, not for groups.";
else
message += "\n\nThe [" + tag + "] tag is not a valid tag.";
alert(message);
cancel = true;
return;
}
} else if (!isValidLayerTag(tag)) {
var message = "Invalid layer name:\n\n" + layer.name;
if (isValidGroupTag(tag))
message += "\n\nThe [" + tag + "] tag is only valid for groups, not for layers.";
else
message += "\n\nThe [" + tag + "] tag is not a valid tag.";
alert(message);
cancel = true;
return;
}
}
// Ensure only one tag.
if (layer.name.replace(/\[[^\]]+\]/, "").search(/\[[^\]]+\]/) != -1) {
alert("A " + (group ? "group" : "layer") + " name must not have more than one tag:\n" + layer.name);
cancel = true;
return;
}
var changeVisibility = layer.kind == LayerKind.NORMAL || group;
if (changeVisibility) {
layer.wasVisible = layer.visible;
layer.visible = true;
if (layer.allLocked) layer.allLocked = false;
}
if (group && findTag(layer, "merge")) {
collectGroupMerge(layer);
if (!layer.layers || layer.layers.length == 0) continue;
} else if (layer.layers && layer.layers.length > 0) {
collectLayers(layer, collect);
continue;
}
if (changeVisibility) layer.visible = false;
collect.push(layer);
}
}
function collectGroupMerge (parent) {
if (!parent.layers) return;
for (var i = parent.layers.length - 1; i >= 0; i--) {
var layer = parent.layers[i];
if (settings.ignoreHiddenLayers && !layer.visible) {
deleteLayer(layer);
continue;
}
if (findTag(layer, "ignore")) {
deleteLayer(layer);
continue;
}
collectGroupMerge(layer);
}
}
function isValidGroupTag (tag) {
switch (tag) {
case "bone":
case "slot":
case "skin":
case "merge":
case "folder":
case "ignore":
return true;
}
return false;
}
function isValidLayerTag (tag) {
switch (tag) {
case "ignore":
return true;
}
return false;
}
function isGroup (layer) {
return layer.typename == "LayerSet";
}
function stripTags (name) {
return trim(name.replace(/\[[^\]]+\]/g, ""));
}
function findTagLayer (layer, tag) {
while (layer) {
if (tag == "ignore" || isGroup(layer)) { // Non-group layers can only have ignore tag.
if (layer.name.toLowerCase().indexOf("[" + tag + "]") != -1) return layer;
}
layer = layer.parent;
}
return null;
}
function findTag (layer, tag, otherwise) {
var found = findTagLayer(layer, tag);
return found ? stripTags(found.name) : otherwise;
}
function jsonPath (jsonPath) {
if (endsWith(jsonPath, ".json")) {
var index = jsonPath.replace("\\", "/").lastIndexOf("/");
if (index != -1) return absolutePath(jsonPath.slice(0, index + 1)) + jsonPath.slice(index + 1);
return absolutePath("./") + jsonPath;
}
var name = decodeURI(originalDoc.name);
return absolutePath(jsonPath) + name.substring(0, name.indexOf(".")) + ".json";
}
function folders (layer, path) {
var folderLayer = findTagLayer(layer, "folder");
return folderLayer ? folders(folderLayer.parent, stripTags(folderLayer.name) + "/" + path) : path;
}
// Photoshop utility:
function scaleImage () {
var imageSize = activeDocument.width.as("px") * settings.scale;
activeDocument.resizeImage(UnitValue(imageSize, "px"), null, null, ResampleMethod.BICUBICSHARPER);
}
var history;
function storeHistory () {
history = activeDocument.activeHistoryState;
}
function restoreHistory () {
activeDocument.activeHistoryState = history;
}
function scriptDir () {
var file;
if (!cs2)
file = $.fileName;
else {
try {
var error = THROW_ERROR; // Force error which provides the script file name.
} catch (ex) {
file = ex.fileName;
}
}
return new File(file).parent + "/";
}
function hasFilePath () {
var action = new ActionReference();
action.putEnumerated(cID("Dcmn"), cID("Ordn"), cID("Trgt"));
return executeActionGet(action).hasKey(sID("fileReference"));
}
function absolutePath (path) {
path = trim(path);
if (!startsWith(path, "./")) {
var absolute = decodeURI(new File(path).absoluteURI);
if (!startsWith(absolute, decodeURI(new File("child").parent.absoluteURI))) return absolute + "/";
path = "./" + path;
}
if (path.length == 0)
path = decodeURI(activeDocument.path);
else if (startsWith(settings.imagesDir, "./"))
path = decodeURI(activeDocument.path) + path.substring(1);
path = (new File(path).fsName).toString();
path = path.replace(/\\/g, "/");
if (path.substring(path.length - 1) != "/") path += "/";
return path;
}
function cID (id) {
return charIDToTypeID(id);
}
function sID (id) {
return stringIDToTypeID(id);
}
function bgColor (control, r, g, b) {
control.graphics.backgroundColor = control.graphics.newBrush(control.graphics.BrushType.SOLID_COLOR, [r, g, b]);
}
function deselectLayers () {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated(cID("Lyr "), cID("Ordn"), cID("Trgt"));
desc.putReference(cID("null"), ref);
executeAction(sID("selectNoLayers"), desc, DialogModes.NO);
}
function convertToRGB () {
var desc = new ActionDescriptor();
desc.putClass(cID("T "), cID("RGBM"));
desc.putBoolean(cID("Mrge"), false);
desc.putBoolean(cID("Rstr"), true);
executeAction(cID("CnvM"), desc, DialogModes.NO);
}
function savePNG (file) {
var options = new PNGSaveOptions();
options.compression = 9;
activeDocument.saveAs(file, options, true, Extension.LOWERCASE);
}
// JavaScript utility:
function countAssocArray (obj) {
var count = 0;
for (var key in obj)
if (obj.hasOwnProperty(key)) count++;
return count;
}
function trim (value) {
return value.replace(/^\s+|\s+$/g, "");
}
function startsWith (str, prefix) {
return str.indexOf(prefix) === 0;
}
function endsWith (str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
function quote (value) {
return '"' + value.replace('"', '\\"') + '"';
}
Binary file not shown.
+9
View File
@@ -0,0 +1,9 @@
1、把插件放到PS的这个目录下:\Adobe Photoshop CS6 (64 Bit)\Presets\Scripts\LayersToPNG.jsx
(如果PS是开着的,需要重启一下)
2、PS内启动脚本的方法:“文件”—“脚本”——“LayersTOPNG”
更多spine源文件,max源文件,bip文件和 好用的工具,请关注我
B站:做动画的大熊
+15
View File
@@ -0,0 +1,15 @@
#target photoshopapp.bringToFront();
if (documents.length == 0) {
alert("没有可处理的文档");
} else {
var visibility = false;
var docRef = activeDocument;
var layers = docRef.layers;
if (layers.length == 1 && docRef.activeLayer.isBackgroundLayer == 1) {
alert("The Background layer can not be hidden when it is the only layer in a document.");
} else {
for (var i = 0; i < layers.length; i++) {
layers[i].name = "" + [i];
}
}
}
+790
View File
@@ -0,0 +1,790 @@
using UnityEditor;
using UnityEngine;
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
public class DependencyOrganizerWindow : EditorWindow
{
private List<UnityEngine.Object> draggedAssets = new List<UnityEngine.Object>();
private Vector2 prefabScroll;
private Vector2 depScroll;
private Dictionary<string, Dictionary<string, bool>> dependenciesByType = new Dictionary<string, Dictionary<string, bool>>();
private Dictionary<string, bool> typeToggle = new Dictionary<string, bool>();
private Dictionary<string, bool> typeFoldout = new Dictionary<string, bool>();
private Dictionary<string, bool> filterTypeToggle = new Dictionary<string, bool>();
// 贴图路径 -> HashSet<材质路径>
private Dictionary<string, HashSet<string>> textureUsedByMaterials = new Dictionary<string, HashSet<string>>();
private string targetRootFolder = string.Empty;
private string lastOrganizeAbsPath = string.Empty;
private SortedDictionary<long, string> undoManifests = new SortedDictionary<long, string>();
private const string UndoManifestDir = "Assets/Editor/DependencyOrganizerUndo";
private const string UndoManifestPrefix = "DependencyOrganizerWindow_undo_";
private Dictionary<string, bool> matsFoldout = new Dictionary<string, bool>();
[MenuItem("Tools/特效依赖整理工具")]
public static void ShowWindow()
{
var w = GetWindow<DependencyOrganizerWindow>("特效依赖整理工具-by很喜欢乱来");
w.minSize = new Vector2(700, 700);
}
private void OnEnable()
{
LoadUndoManifests();
InitFilterTypeToggle();
}
private void InitFilterTypeToggle()
{
string[] filterTypes = new string[] {
"Textures", "Materials", "Models", "Shaders", "Scripts",
"Prefabs", "Animations", "Animators", "Audio", "Physics", "Others"
};
foreach (var t in filterTypes)
{
if (!filterTypeToggle.ContainsKey(t))
filterTypeToggle[t] = true;
}
}
private void OnGUI()
{
GUILayout.Label("依赖整理工具-by很喜欢乱来", EditorStyles.boldLabel);
EditorGUILayout.HelpBox(
"1. 拖入Prefab/Scene/ScriptableObject等资源。\n" +
"2. 点击“收集依赖资源”,按类型和文件复选。\n" +
"3. 支持折叠、全选/反选。\n" +
"4. 选择目标根目录(支持拖入文件夹)。\n" +
"5. 点击“整理”移动资源,自动避免冲突重命名。\n" +
"6. 支持多版本撤销。\n" +
"7. 支持导出UnityPackage。\n" +
"8. 移动时显示进度条。\n" +
"9. 显示资源大小预估。\n" +
"10. 资源名点击定位,右键复制资源名。\n" +
"11. 贴图资源显示被哪些材质引用,材质路径列表可点击定位。\n",
MessageType.Info);
EditorGUILayout.Space();
DrawFilterTypeToggle();
EditorGUILayout.Space();
DrawDragArea();
DrawPrefabList();
EditorGUILayout.Space();
if (GUILayout.Button("收集依赖资源", GUILayout.Height(30)))
CollectDependencies();
EditorGUILayout.Space();
DrawDependenciesList();
EditorGUILayout.Space();
DrawSizeEstimate();
EditorGUILayout.Space();
DrawTargetFolderSelector();
EditorGUILayout.Space();
DrawActionButtons();
EditorGUILayout.Space();
DrawUndoHistory();
}
private void DrawFilterTypeToggle()
{
EditorGUILayout.BeginHorizontal();
foreach (var key in new List<string>(filterTypeToggle.Keys))
{
bool val = filterTypeToggle[key];
bool newVal = GUILayout.Toggle(val, key, "Button", GUILayout.Height(22));
if (newVal != val)
{
filterTypeToggle[key] = newVal;
}
}
EditorGUILayout.EndHorizontal();
}
private void DrawDragArea()
{
Rect dropArea = GUILayoutUtility.GetRect(0, 60, GUILayout.ExpandWidth(true));
GUI.Box(dropArea, "拖入Prefab/Scene/ScriptableObject/Hierarchy中的GameObject");
var evt = Event.current;
if ((evt.type == EventType.DragUpdated || evt.type == EventType.DragPerform) && dropArea.Contains(evt.mousePosition))
{
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
if (evt.type == EventType.DragPerform)
{
DragAndDrop.AcceptDrag();
foreach (var obj in DragAndDrop.objectReferences)
{
string path = AssetDatabase.GetAssetPath(obj);
if (obj is GameObject go)
{
bool isPrefab = !string.IsNullOrEmpty(path) && path.StartsWith("Assets");
if (isPrefab)
{
if (!draggedAssets.Contains(obj))
draggedAssets.Add(obj);
}
else
{
GameObject prefabRoot = PrefabUtility.GetCorrespondingObjectFromSource(go);
if (prefabRoot != null && !draggedAssets.Contains(prefabRoot))
draggedAssets.Add(prefabRoot);
else if (!draggedAssets.Contains(obj))
draggedAssets.Add(obj);
}
}
else if (IsSupportedAsset(obj, path))
{
if (!draggedAssets.Contains(obj))
draggedAssets.Add(obj);
}
}
}
evt.Use();
}
}
private bool IsSupportedAsset(UnityEngine.Object obj, string path)
{
if (obj == null || string.IsNullOrEmpty(path)) return false;
return (obj is GameObject && path.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase))
|| path.EndsWith(".unity", StringComparison.OrdinalIgnoreCase)
|| obj is ScriptableObject;
}
private void DrawPrefabList()
{
EditorGUILayout.LabelField("已拖入资源:");
if (draggedAssets.Count > 0)
{
if (GUILayout.Button("清空列表", GUILayout.Width(80)))
{
draggedAssets.Clear();
dependenciesByType.Clear();
typeToggle.Clear();
typeFoldout.Clear();
textureUsedByMaterials.Clear();
matsFoldout.Clear();
}
}
prefabScroll = EditorGUILayout.BeginScrollView(prefabScroll, GUILayout.Height(100));
for (int i = draggedAssets.Count - 1; i >= 0; i--)
{
EditorGUILayout.BeginHorizontal();
draggedAssets[i] = EditorGUILayout.ObjectField(draggedAssets[i], typeof(UnityEngine.Object), false);
if (GUILayout.Button("移除", GUILayout.Width(60)))
draggedAssets.RemoveAt(i);
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
}
private void CollectDependencies()
{
dependenciesByType.Clear();
typeToggle.Clear();
typeFoldout.Clear();
textureUsedByMaterials.Clear();
matsFoldout.Clear();
if (draggedAssets.Count == 0)
{
EditorUtility.DisplayDialog("提示", "请先拖入至少一个资源。", "确定");
return;
}
HashSet<string> allDeps = new HashSet<string>();
foreach (var obj in draggedAssets)
{
string origPath = AssetDatabase.GetAssetPath(obj);
var deps = AssetDatabase.GetDependencies(origPath, true);
foreach (var dep in deps)
{
if (!dep.StartsWith("Assets/") || dep.StartsWith("Assets/Editor/") || dep.Contains("Packages/"))
continue;
allDeps.Add(dep);
}
}
// 构建贴图->材质引用映射
foreach (var dep in allDeps)
{
Type type = AssetDatabase.GetMainAssetTypeAtPath(dep);
if (type == typeof(Material))
{
Material mat = AssetDatabase.LoadAssetAtPath<Material>(dep);
if (mat == null) continue;
Shader shader = mat.shader;
int propertyCount = ShaderUtil.GetPropertyCount(shader);
for (int i = 0; i < propertyCount; i++)
{
if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv)
{
string propName = ShaderUtil.GetPropertyName(shader, i);
Texture tex = mat.GetTexture(propName);
if (tex != null)
{
string texPath = AssetDatabase.GetAssetPath(tex);
if (!string.IsNullOrEmpty(texPath))
{
if (!textureUsedByMaterials.TryGetValue(texPath, out var mats))
{
mats = new HashSet<string>();
textureUsedByMaterials[texPath] = mats;
}
mats.Add(dep);
}
}
}
}
}
}
foreach (var dep in allDeps)
{
Type type = AssetDatabase.GetMainAssetTypeAtPath(dep);
string folder = GetTargetFolder(type, dep);
if (!dependenciesByType.ContainsKey(folder))
dependenciesByType[folder] = new Dictionary<string, bool>();
if (!dependenciesByType[folder].ContainsKey(dep))
dependenciesByType[folder][dep] = true;
if (!typeToggle.ContainsKey(folder))
typeToggle[folder] = true;
if (!typeFoldout.ContainsKey(folder))
typeFoldout[folder] = false;
}
}
private void DrawDependenciesList()
{
if (dependenciesByType.Count == 0) return;
float availableHeight = position.height - 550f;
if (availableHeight < 150f) availableHeight = 150f;
depScroll = EditorGUILayout.BeginScrollView(depScroll, GUILayout.Height(availableHeight));
foreach (var kvp in dependenciesByType)
{
string type = kvp.Key;
var filesDict = kvp.Value;
if (!filterTypeToggle.TryGetValue(type, out bool showType) || !showType)
continue;
if (!typeFoldout.ContainsKey(type)) typeFoldout[type] = false;
if (!typeToggle.ContainsKey(type)) typeToggle[type] = true;
EditorGUILayout.BeginVertical("box");
EditorGUILayout.BeginHorizontal();
typeFoldout[type] = EditorGUILayout.Foldout(typeFoldout[type], $"{type} ({filesDict.Count})", true);
if (GUILayout.Button("全选", GUILayout.Width(40)))
{
typeToggle[type] = true;
foreach (var k in filesDict.Keys.ToList())
filesDict[k] = true;
}
if (GUILayout.Button("反选", GUILayout.Width(40)))
{
bool allSelected = filesDict.Values.All(v => v);
foreach (var k in filesDict.Keys.ToList())
filesDict[k] = !allSelected;
typeToggle[type] = filesDict.Values.Any(v => v);
}
EditorGUILayout.EndHorizontal();
bool newTypeToggle = EditorGUILayout.ToggleLeft("选择该类型全部文件", typeToggle[type]);
if (newTypeToggle != typeToggle[type])
{
typeToggle[type] = newTypeToggle;
foreach (var k in filesDict.Keys.ToList())
filesDict[k] = newTypeToggle;
}
if (typeFoldout[type])
{
EditorGUI.indentLevel++;
foreach (var fileKey in filesDict.Keys.ToList())
{
bool selected = filesDict[fileKey];
EditorGUILayout.BeginHorizontal(GUILayout.Height(22));
GUILayout.Space(6 * (EditorGUI.indentLevel - 1));
Rect toggleRect = GUILayoutUtility.GetRect(24, 22, GUILayout.Width(24));
bool newSelected = EditorGUI.Toggle(toggleRect, selected);
if (newSelected != selected)
filesDict[fileKey] = newSelected;
if (!newSelected)
GUI.enabled = false;
string fileName = Path.GetFileName(fileKey);
GUIContent fileNameContent = new GUIContent(fileName);
Vector2 fileNameSize = EditorStyles.boldLabel.CalcSize(fileNameContent);
float fileNameWidth = Mathf.Min(fileNameSize.x, 200);
GUILayout.Space(6);
Rect fileNameRect = GUILayoutUtility.GetRect(fileNameWidth, 22, GUILayout.Width(fileNameWidth));
GUI.Label(fileNameRect, fileName, EditorStyles.boldLabel);
if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && fileNameRect.Contains(Event.current.mousePosition))
{
var obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(fileKey);
if (obj != null)
{
EditorGUIUtility.PingObject(obj);
Event.current.Use();
}
}
else if (Event.current.type == EventType.ContextClick && fileNameRect.Contains(Event.current.mousePosition))
{
Event.current.Use();
GenericMenu menu = new GenericMenu();
menu.AddItem(new GUIContent("复制资源名称"), false, () =>
{
GUIUtility.systemCopyBuffer = fileName;
});
menu.ShowAsContext();
}
GUILayout.Label(fileKey, EditorStyles.miniLabel, GUILayout.ExpandWidth(true));
if (GUILayout.Button("定位", GUILayout.Width(60)))
{
var obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(fileKey);
if (obj != null)
EditorGUIUtility.PingObject(obj);
}
if (!newSelected)
GUI.enabled = true;
EditorGUILayout.EndHorizontal();
if (textureUsedByMaterials.TryGetValue(fileKey, out var mats) && mats.Count > 0)
{
if (!matsFoldout.ContainsKey(fileKey)) matsFoldout[fileKey] = false;
Rect foldoutRect = GUILayoutUtility.GetRect(130, EditorGUIUtility.singleLineHeight);
matsFoldout[fileKey] = EditorGUI.Foldout(foldoutRect, matsFoldout[fileKey], $"引用于 {mats.Count} 个材质", true);
if (matsFoldout[fileKey])
{
EditorGUI.indentLevel++;
foreach (var matPath in mats)
{
Rect matRect = GUILayoutUtility.GetRect(20, 18);
GUILayout.Space(6 * (EditorGUI.indentLevel - 1));
if (GUI.Button(matRect, matPath, EditorStyles.linkLabel))
{
var matObj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(matPath);
if (matObj != null)
EditorGUIUtility.PingObject(matObj);
}
}
EditorGUI.indentLevel--;
}
}
}
EditorGUI.indentLevel--;
}
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndScrollView();
}
private void DrawSizeEstimate()
{
long totalBytes = 0;
foreach (var kvp in dependenciesByType)
{
foreach (var path in kvp.Value.Keys)
{
string absPath = Path.Combine(Application.dataPath, path.Substring("Assets/".Length));
if (File.Exists(absPath))
{
totalBytes += new FileInfo(absPath).Length;
}
}
}
EditorGUILayout.LabelField($"预估待移动资源大小: {totalBytes / 1024f / 1024f:F2} MB");
}
private void DrawTargetFolderSelector()
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("目标根目录:", GUILayout.Width(80));
GUIStyle boxStyle = GUI.skin.box;
Rect dragRect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth - 100, EditorGUIUtility.singleLineHeight + 6);
GUI.Box(dragRect, "", boxStyle);
GUI.Label(dragRect, string.IsNullOrEmpty(targetRootFolder) ? "<拖入目标根目录文件夹>" : targetRootFolder, EditorStyles.label);
Event evt = Event.current;
if ((evt.type == EventType.DragUpdated || evt.type == EventType.DragPerform) && dragRect.Contains(evt.mousePosition))
{
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
if (evt.type == EventType.DragPerform)
{
DragAndDrop.AcceptDrag();
if (DragAndDrop.objectReferences.Length > 0)
{
UnityEngine.Object obj = DragAndDrop.objectReferences[0];
string path = AssetDatabase.GetAssetPath(obj);
if (AssetDatabase.IsValidFolder(path))
{
targetRootFolder = path;
evt.Use();
EditorGUIUtility.ExitGUI();
return;
}
}
if (DragAndDrop.paths != null && DragAndDrop.paths.Length > 0)
{
string firstPath = DragAndDrop.paths[0];
if (Directory.Exists(firstPath))
{
string absDataPath = Application.dataPath.Replace("/", "\\");
string absFirstPath = firstPath.Replace("/", "\\");
if (absFirstPath.StartsWith(absDataPath))
{
string relativePath = "Assets" + absFirstPath.Substring(absDataPath.Length);
targetRootFolder = relativePath.Replace("\\", "/");
evt.Use();
EditorGUIUtility.ExitGUI();
return;
}
}
}
evt.Use();
}
else
{
evt.Use();
}
}
EditorGUILayout.EndHorizontal();
}
private void DrawActionButtons()
{
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("整理", GUILayout.Height(30))) MoveSelectedDependencies();
if (GUILayout.Button("导出 UnityPackage", GUILayout.Height(30))) ExportPackage();
if (GUILayout.Button("撤销", GUILayout.Height(30))) ShowUndoMenu();
if (!string.IsNullOrEmpty(lastOrganizeAbsPath) && GUILayout.Button("打开生成路径", GUILayout.Height(30)))
EditorUtility.RevealInFinder(lastOrganizeAbsPath);
EditorGUILayout.EndHorizontal();
}
private void DrawUndoHistory()
{
if (undoManifests.Count == 0)
{
EditorGUILayout.LabelField("暂无撤销历史");
return;
}
EditorGUILayout.LabelField("撤销历史记录:");
foreach (var kvp in undoManifests.Reverse())
{
string label = DateTimeOffset.FromUnixTimeMilliseconds(kvp.Key).ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
EditorGUILayout.LabelField(label);
}
}
private void ShowUndoMenu()
{
if (undoManifests.Count == 0)
{
EditorUtility.DisplayDialog("提示", "没有可用的撤销记录。", "确定");
return;
}
GenericMenu menu = new GenericMenu();
foreach (var kvp in undoManifests.Reverse())
{
string label = DateTimeOffset.FromUnixTimeMilliseconds(kvp.Key).ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
string path = kvp.Value;
menu.AddItem(new GUIContent(label), false, () =>
{
UndoMoveAssets(path);
});
}
menu.ShowAsContext();
}
private void UndoMoveAssets(string manifestPath)
{
if (!File.Exists(manifestPath))
{
EditorUtility.DisplayDialog("错误", "撤销文件不存在。", "确定");
RemoveManifestByPath(manifestPath);
return;
}
string json = File.ReadAllText(manifestPath);
var manifest = JsonUtility.FromJson<MoveManifest>(json);
if (manifest == null || manifest.entries == null)
{
EditorUtility.DisplayDialog("错误", "撤销文件格式错误。", "确定");
return;
}
AssetDatabase.StartAssetEditing();
try
{
foreach (var e in manifest.entries.Reverse())
{
if (AssetDatabase.MoveAsset(e.destPath, e.originalPath).Length == 0)
Debug.Log($"已恢复 {e.destPath}");
else
Debug.LogWarning($"恢复失败或路径冲突: {e.destPath}");
}
}
finally
{
AssetDatabase.StopAssetEditing();
AssetDatabase.Refresh();
}
File.Delete(manifestPath);
RemoveManifestByPath(manifestPath);
EditorUtility.DisplayDialog("撤销完成", "资源已恢复。", "确定");
}
private void RemoveManifestByPath(string manifestPath)
{
var keysToRemove = undoManifests.Where(kvp => kvp.Value == manifestPath).Select(kvp => kvp.Key).ToList();
foreach (var key in keysToRemove)
undoManifests.Remove(key);
}
private void LoadUndoManifests()
{
undoManifests.Clear();
if (!AssetDatabase.IsValidFolder(UndoManifestDir))
return;
string fullDir = Path.Combine(Application.dataPath, "Editor/DependencyOrganizerUndo");
if (!Directory.Exists(fullDir))
return;
foreach (var file in Directory.GetFiles(fullDir, UndoManifestPrefix + "*.json"))
{
try
{
string fileName = Path.GetFileNameWithoutExtension(file);
string timestampStr = fileName.Substring(UndoManifestPrefix.Length);
if (long.TryParse(timestampStr, out long ts))
undoManifests[ts] = file;
}
catch { }
}
}
private void MoveSelectedDependencies()
{
if (draggedAssets.Count == 0)
{
EditorUtility.DisplayDialog("提示", "请先拖入至少一个资源。", "确定");
return;
}
if (dependenciesByType.Count == 0)
{
EditorUtility.DisplayDialog("提示", "请先收集依赖资源。", "确定");
return;
}
if (!AssetDatabase.IsValidFolder(UndoManifestDir))
AssetDatabase.CreateFolder("Assets/Editor", "DependencyOrganizerUndo");
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
string manifestFile = $"{UndoManifestDir}/{UndoManifestPrefix}{timestamp}.json";
List<MoveEntry> moves = new List<MoveEntry>();
List<(string originalPath, string destPath)> movesToDo = new List<(string, string)>();
AssetDatabase.StartAssetEditing();
try
{
foreach (var obj in draggedAssets)
{
string origPath = AssetDatabase.GetAssetPath(obj);
string root;
if (!string.IsNullOrEmpty(targetRootFolder) && AssetDatabase.IsValidFolder(targetRootFolder))
{
root = targetRootFolder;
}
else
{
string exportBase = "Assets/export";
if (!AssetDatabase.IsValidFolder(exportBase))
AssetDatabase.CreateFolder("Assets", "export");
string name = Path.GetFileNameWithoutExtension(origPath);
root = $"{exportBase}/{name}";
if (!AssetDatabase.IsValidFolder(root))
AssetDatabase.CreateFolder(exportBase, name);
}
lastOrganizeAbsPath = Path.GetFullPath(root);
var deps = AssetDatabase.GetDependencies(origPath, true);
foreach (var dep in deps)
{
if (!dep.StartsWith("Assets/") || dep.StartsWith("Assets/Editor/") || dep.Contains("Packages/"))
continue;
if (movesToDo.Any(m => m.destPath == dep) || dep.StartsWith(root + "/"))
continue;
Type type = AssetDatabase.GetMainAssetTypeAtPath(dep);
string folder = GetTargetFolder(type, dep);
if (!dependenciesByType.TryGetValue(folder, out var filesDict))
continue;
if (!filesDict.TryGetValue(dep, out bool moveThis) || !moveThis)
continue;
string dstDir = $"{root}/{folder}";
if (!AssetDatabase.IsValidFolder(dstDir))
AssetDatabase.CreateFolder(root, folder);
string dst = GetUniqueAssetPath($"{dstDir}/{Path.GetFileName(dep)}");
movesToDo.Add((dep, dst));
}
}
int total = movesToDo.Count;
for (int i = 0; i < total; i++)
{
var (src, dst) = movesToDo[i];
EditorUtility.DisplayProgressBar("移动资源", $"正在移动 {Path.GetFileName(src)} ({i + 1}/{total})", (float)i / total);
string err = AssetDatabase.MoveAsset(src, dst);
if (string.IsNullOrEmpty(err))
moves.Add(new MoveEntry(src, dst));
else
Debug.LogWarning($"移动失败: {src} -> {dst},错误:{err}");
}
}
finally
{
EditorUtility.ClearProgressBar();
AssetDatabase.StopAssetEditing();
AssetDatabase.Refresh();
}
File.WriteAllText(manifestFile, JsonUtility.ToJson(new MoveManifest { entries = moves.ToArray() }, true));
AssetDatabase.ImportAsset(manifestFile);
LoadUndoManifests();
EditorUtility.DisplayDialog("整理完成", $"共移动 {moves.Count} 个资源,存放于 {(!string.IsNullOrEmpty(targetRootFolder) ? targetRootFolder : "Assets/export")}", "确定");
}
private string GetTargetFolder(Type type, string path)
{
string ext = Path.GetExtension(path).ToLowerInvariant();
if (new[] { ".cs" }.Contains(ext)) return "Scripts";
if (new[] { ".fbx", ".obj", ".blend" }.Contains(ext)) return "Models";
if (new[] { ".anim" }.Contains(ext) || type == typeof(AnimationClip)) return "Animations";
if (new[] { ".controller" }.Contains(ext) || type == typeof(UnityEditor.Animations.AnimatorController)) return "Animators";
if (new[] { ".shader", ".shadergraph" }.Contains(ext) || type == typeof(Shader)) return "Shaders";
if (new[] { ".png", ".jpg", ".jpeg", ".tga", ".psd", ".exr" }.Contains(ext) || type == typeof(Texture2D)) return "Textures";
if (new[] { ".wav", ".mp3", ".ogg" }.Contains(ext) || type == typeof(AudioClip)) return "Audio";
if (ext == ".mat" || type == typeof(Material)) return "Materials";
if (ext == ".physicmaterial" || type == typeof(PhysicMaterial)) return "Physics";
if (ext == ".prefab" || type == typeof(GameObject)) return "Prefabs";
return "Others";
}
private string GetUniqueAssetPath(string desiredPath)
{
string path = desiredPath;
string dir = Path.GetDirectoryName(desiredPath);
string filename = Path.GetFileNameWithoutExtension(desiredPath);
string ext = Path.GetExtension(desiredPath);
int count = 1;
while (AssetPathExists(path))
{
path = $"{dir}/{filename}_{count}{ext}";
count++;
}
return path;
}
private bool AssetPathExists(string path)
{
return AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(path) != null;
}
private void ExportPackage()
{
string exportRel = !string.IsNullOrEmpty(targetRootFolder) && AssetDatabase.IsValidFolder(targetRootFolder)
? targetRootFolder : "Assets/export";
if (!AssetDatabase.IsValidFolder(exportRel))
{
EditorUtility.DisplayDialog("错误", $"导出目录无效:{exportRel}", "确定");
return;
}
var guids = AssetDatabase.FindAssets("", new[] { exportRel });
var paths = guids.Select(AssetDatabase.GUIDToAssetPath).ToArray();
string save = EditorUtility.SaveFilePanel("保存 UnityPackage", Application.dataPath, "Package.unitypackage", "unitypackage");
if (string.IsNullOrEmpty(save)) return;
AssetDatabase.ExportPackage(paths, save, ExportPackageOptions.Default);
EditorUtility.DisplayDialog("导出成功", $"已导出 {paths.Length} 个资源到 {save}", "确定");
}
[Serializable]
private class MoveEntry
{
public string originalPath;
public string destPath;
public MoveEntry(string o, string d) { originalPath = o; destPath = d; }
}
[Serializable]
private class MoveManifest
{
public MoveEntry[] entries;
}
}
+2
View File
@@ -0,0 +1,2 @@
1.DependencyOrganizer.cs
脚本需要放在unity工程的Asset/Editor下面,然后菜单工具栏(Tool)下面会出现相关工具按钮
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+39
View File
@@ -0,0 +1,39 @@
bip=$.controller
--a=$'Bip002 R Thigh'.Controller
--biped.saveBipFile bip "C:\Users\ab\Desktop\savetest.bip"
--biped.loadBipFile bip "C:\Users\ab\Desktop\savetest.bip"
--biped.clearAllAnimation bip
--biped.mirror bip
biped.copyPosture bip (#pose) 1 1 1
--biped.pastePosture bip #posture 0 "0001"
--biped.loadCopyPasteFile bip "C:\Users\ab\Desktop\savetest.cpy"
--biped.saveCopyPasteFile bip "C:\Users\ab\Desktop\savetest1.cpy"
--biped.numCopies bip #pose
--biped.deleteCopy bip #posture "abc"
--biped.setCopyName bip #posture 2 "def"
--biped.getCopyName bip #posture 1
--biped.createCopyCollection bip "ghi"
--biped.numCopyCollections bip
--collection001=biped.getCopyCollection bip 1
--biped.deleteCopyCollection bip 1
--arr=#()
--biped.copyBipPosture bip collection001 arr #snapview
--coll=biped.createCopyCollection bip abc
--biped.copyBipPose bip 1 1
+15
View File
@@ -0,0 +1,15 @@
nums=3
b=$Point001
c=$Point002
a=#()
a[1]=b
for i=1 to (nums-1) do
(
a[i+1]=point()
a[i+1].pos=(i*c.pos+(nums-i)*b.pos)/nums
)
a[nums+1]=c
+1
View File
@@ -0,0 +1 @@
OpzeyetgcunSGXfRDPnbhvl4Y4U0n8oNolqvWh4xtwWHUoar5xpJGlx8WQ07J02/Xt9CH2qpPNBcO8Rep8GOxez8SUPzEw8xSQxpkHoIHvsdNiBDZCxQTZU5MaB/8SfuTESosGV3p5AQ2aqFaKrpGABBSGebgfL75uDHmSFq8ME=
+1
View File
@@ -0,0 +1 @@
<RSAKeyValue><Modulus>zyQ7zokCM/wHwJrb89hKyzC4LTPDCvR7qw8sIuJLGsbPJqJReTgAxxDyZNrIobDjO2M5OaCljSP2VDv6lxwMG8wNlyKoy5opBtWjUtZgc+/H54hppLGmgaWR3pYmojEomHw5gmFdAWZpz42yf3QO4ehYIVHuOpeXJpBpdEgrY2k=</Modulus><Exponent>AQAB</Exponent><P>4lUl/1Skw5S3xuXSh3gYzVQFyqAsrnJeENQxJ8Abx1PR2Gck+wkcadaqdRD+9sLeff9rsVwAObGAGzfQ2mBzow==</P><Q>6ksbSrCw14U2XOWrLyQynyodtHYBoMQRfS0uUTwJutCgb+Rfe56Lfv4nUXnC/GpiZkuXnZsKcLNvyB1PQtpdgw==</Q><DP>T3/xNNqadUiLtQWNCaCZtaXJ0v6oMy5g9DBUg83q8/zxPL4eMz9kB5krjqtFo4+Xb1KElWvneFxszyKv7cTrWQ==</DP><DQ>4oSO9F1z/Er8zj/2i3NRxfSwF4Nn+4jU59NAzqVfOtDt7IA9mIUmlTcfyHQSgnxQelpnUadOJrw1PKKpuRbqBQ==</DQ><InverseQ>IXxMkGm2cn7esrIdZBTXv8gOmV8DBP3ERleT3VBUfyR4Qa1uhJ8agGZdDm/TcLlte45uUHhgPJuSYvjLo7ZLBA==</InverseQ><D>yY2vKAtGeoC8plvIs998/3M7crhQC2PSxaKwxoy8maRjQmtkrXehwhEqWppL6JDuugWVVA6Np+UbNeFatxhSaiWRJJv0iccR0GyT38vWGbmN2FNew+2KsP/+2MDva3z8o5OZ+p0bsqUwiTL05z71zK/dd5tZHGhHmM4W3sMdbKU=</D></RSAKeyValue>
@@ -0,0 +1,35 @@
-- 使用私钥进行解密的函数
fn decryptWithPrivateKey encryptedData privateKey =
(
rsaProvider = dotnetobject "System.Security.Cryptography.RSACryptoServiceProvider"
rsaProvider.FromXmlString(privateKey)
methodprivatekey = (dotnetclass "System.Security.Cryptography.RSAEncryptionPadding").Pkcs1
try(
-- 使用私钥解密字节数组
decryptedBytes = rsaProvider.Decrypt encryptedData methodprivatekey
-- 将字节数组转换为文本
decryptedText = (dotnetclass "System.Text.Encoding").UTF8.GetString(decryptedBytes)
return decryptedText)catch(return "解密错误!!!")
)
-- 从文件中读取加密后的数据
encryptedDataFilePath = getFilenamePath(getThisScriptFilename()) + "data.txt"
streamReader = dotnetobject "System.IO.StreamReader" encryptedDataFilePath
encryptedData = (dotnetclass "System.Convert").FromBase64String(streamReader.ReadLine())
streamReader.Close()
-- 从文件中读取私钥
privateKeyFilePath = getFilenamePath(getThisScriptFilename()) + "privateKey.xml"
streamReader = dotnetobject "System.IO.StreamReader" privateKeyFilePath
privateKey = streamReader.ReadToEnd()
streamReader.Close()
-- 示例:使用私钥解密之前加密的数据
decryptedText = decryptWithPrivateKey encryptedData privateKey
-- 输出解密后的数据
print decryptedText
@@ -0,0 +1,44 @@
-- 使用非对称加密进行加密的函数
fn encryptWithPublicKey plaintext publicKey =
(
rsaProvider = dotnetobject "System.Security.Cryptography.RSACryptoServiceProvider"
rsaProvider.FromXmlString(publicKey)
methodpublickey = (dotnetclass "System.Security.Cryptography.RSAEncryptionPadding").Pkcs1
-- 将文本转换为字节数组
plaintextBytes = (dotnetclass "System.Text.Encoding").UTF8.GetBytes(plaintext)
-- 使用公钥加密字节数组
encryptedData = rsaProvider.Encrypt plaintextBytes methodpublickey
return encryptedData
)
-- 要加密的文字内容
plaintext = "我是机密,不能告诉其他人。"
-- 生成公钥和私钥
rsaProvider = dotnetobject "System.Security.Cryptography.RSACryptoServiceProvider"
publicKey = rsaProvider.ToXmlString(false)
privateKey = rsaProvider.ToXmlString(true)
-- 将私钥保存到文件
privateKeyFilePath = getFilenamePath(getThisScriptFilename()) +"privateKey.xml"
streamWriter = dotnetobject "System.IO.StreamWriter" privateKeyFilePath
streamWriter.WriteLine(privateKey)
streamWriter.Close()
-- 使用公钥加密
encryptedData = encryptWithPublicKey plaintext publicKey
-- 将加密后的字节数组转换为Base64字符串
encryptedDataString = (dotnetclass "System.Convert").ToBase64String(encryptedData)
-- 将加密后的数据保存到文件
encryptedDataFilePath = getFilenamePath(getThisScriptFilename()) +"data.txt"
streamWriter = dotnetobject "System.IO.StreamWriter" encryptedDataFilePath
streamWriter.WriteLine(encryptedDataString)
streamWriter.Close()
+408
View File
@@ -0,0 +1,408 @@
/*
编写代码注意事项:
1.控件移除后,不可访问任何属性以及数值
2.子栏目的高度固定为600,添加到子栏目后,原卷展栏的高度会失效
*/
if RigToolUI != undefined do (try(destroydialog RigToolUI)catch())
global L_rollout=#() --左侧子栏目
global R_rollout=#() --右侧子栏目
fn remove_L_rollout= --移除左侧子栏目
(
local ui_height=RigToolUI.height
for i=1 to L_rollout.count do removesubrollout RigToolUI.RTleft L_rollout[i]
free L_rollout
if (ui_height>=600) and (L_rollout.count==0) and (R_rollout.count==0) then RigToolUI.height -=600
)
fn remove_R_rollout= --移除右侧子栏目
(
local ui_height=RigToolUI.height
for i=1 to R_rollout.count do removesubrollout RigToolUI.RTright R_rollout[i]
free R_rollout
if (ui_height>=600) and (L_rollout.count==0) and (R_rollout.count==0) then RigToolUI.height -=600
)
rollout NewRig "新建绑定" width:300 height:600
(
--bitmap bmp1 "Bitmap" pos:[10,10] width:285 height:140 align:#center fileName:("C:\Users\ab\Desktop\RigTool\ctrlcolor\mainabout.png") --bitmap:(bitmap 285 140 color:[255,255,255])
label lab01 "请输入新绑定名称:"
edittext cus_rig_name "" width:250 align:#center
button apply_name "确定" width:50 height:30
)
rollout setupmodules "模块创建" width:318 height:300
(
GroupBox RTspline "条带样条线模块(脖子,脊椎)" width:290 height:120 pos:[10,10]
edittext pre_spline_name "名称" pos:[30,30] width:250
spinner spline_joints "关节数量" pos:[30,50] width:250 range:[0,100,3] type:#integer
radiobuttons spline_twisk "" labels:#("X轴扭曲","Y轴扭曲") pos:[30,70] columns:2
checkbox spline_mirror "镜像模块" pos:[210,70] checked:false
button creatspline "创建条带" pos:[80,90] width:150 height:30
button spline_help "说明" pos:[250,90] width:35 height:30
GroupBox RTarms "手臂模块" width:290 height:180 pos:[10,140]
edittext pre_arm_name "名称" pos:[30,160] width:250
spinner upperarm_twistjoints "上臂扭曲骨骼" pos:[30,180] width:250 range:[0,100,2] type:#integer
spinner lowerarm_twistjoints "下臂扭曲骨骼" pos:[30,200] width:250 range:[0,100,2] type:#integer
radiobuttons arm_elbow_joints "" labels:#("单肘部关节","双肘部关节") pos:[30,220] columns:2
spinner midarm_twistjoints "中部扭曲骨骼" pos:[30,240] width:250 range:[0,100,2] type:#integer enabled:false
radiobuttons arm_mirror "" labels:#("仅左臂","双臂","仅右臂") pos:[30,260] default:2 columns:3
button creatarm "创建手臂" pos:[80,280] width:150 height:30
button arm_help "说明" pos:[250,280] width:35 height:30
on arm_elbow_joints changed sel do
if sel==2 then midarm_twistjoints.enabled=true else midarm_twistjoints.enabled=false
GroupBox RTlegs "腿部模块" width:290 height:180 pos:[10,330]
edittext pre_leg_name "名称" pos:[30,350] width:250
spinner upperleg_twistjoints "大腿扭曲骨骼" pos:[30,370] width:250 range:[0,100,2] type:#integer
spinner lowerleg_twistjoints "小腿扭曲骨骼" pos:[30,390] width:250 range:[0,100,2] type:#integer
radiobuttons leg_elbow_joints "" labels:#("单膝盖关节","双膝盖关节") pos:[30,410] columns:2
spinner midleg_twistjoints "中部扭曲骨骼" pos:[30,430] width:250 range:[0,100,2] type:#integer enabled:false
radiobuttons leg_mirror "" labels:#("仅左腿","双腿","仅右腿") pos:[30,450] default:2 columns:3
button creatleg "创建腿部" pos:[80,470] width:150 height:30
button leg_help "说明" pos:[250,470] width:35 height:30
on leg_elbow_joints changed sel do
if sel==2 then midleg_twistjoints.enabled=true else midleg_twistjoints.enabled=false
GroupBox RTFKchains "FK链模块(手指,舌头,尾巴,触须等)" width:290 height:170 pos:[10,520]
edittext pre_fkchains_name "名称" pos:[30,540] width:250
spinner fkchains_num "链条数量" pos:[30,560] width:250 range:[0,100,1] type:#integer
spinner fkchains_joints "每条链关节数" pos:[30,580] width:250 range:[0,100,1] type:#integer
radiobuttons fkchains_outer "" labels:#("X朝前","Y朝前","Z朝前","X朝后","Y朝后","Z朝后") pos:[30,600] default:2 columns:3
checkbox fkchains_mirror "镜像模块" pos:[30,630] checked:true
button creatfkchains "创建FK链" pos:[80,650] width:150 height:30
button fkchains_help "说明" pos:[250,650] width:35 height:30
GroupBox RThead "头部模块" width:290 height:140 pos:[10,700]
edittext pre_head_name "名称" pos:[30,720] width:250
checkbox jaw "下巴" pos:[30,740] checked:true
radiobuttons head_twist "" labels:#("X轴扭曲","Y轴扭曲") pos:[30,760] default:1 columns:2
checkbox head_mirror "镜像模块" pos:[30,780] checked:true
button creathead "创建头部" pos:[80,800] width:150 height:30
button head_help "说明" pos:[250,800] width:35 height:30
GroupBox RTlookat "注视模块" width:290 height:150 pos:[10,850]
edittext pre_lookat_name "名称" pos:[30,870] width:250
spinner lookat_joints "关节数量" pos:[30,890] width:250 range:[0,100,1] type:#integer
radiobuttons lookat_outer "" labels:#("X朝前","Y朝前","Z朝前","X朝后","Y朝后","Z朝后") pos:[30,910] default:2 columns:3
checkbox lookat_mirror "镜像模块" pos:[30,940] checked:true
button creatlookat "创建注视" pos:[80,960] width:150 height:30
button lookat_help "说明" pos:[250,960] width:35 height:30
GroupBox RTauxiliary "辅助关节模块" width:290 height:100 pos:[10,1010]
edittext pre_auxiliary_name "名称" pos:[30,1030] width:250
checkbox auxiliary_mirror "镜像关节" pos:[30,1050] checked:true
button creatauxiliary "创建辅助关节" pos:[80,1070] width:150 height:30
button auxiliary_help "说明" pos:[250,1070] width:35 height:30
)
rollout editmodules "模块编辑" width:318 height:300
(
GroupBox RTspline "条带样条线模块(脖子,脊椎)" width:290 height:120 pos:[10,10]
edittext pre_spline_name "名称" pos:[30,30] width:250
spinner spline_joints "关节数量" pos:[30,50] width:250 range:[0,100,3] type:#integer
radiobuttons spline_twisk "" labels:#("X轴扭曲","Y轴扭曲") pos:[30,70] columns:2
button creatspline "应用条带" pos:[80,90] width:150 height:30
button spline_load "载入" pos:[20,90] width:35 height:30
button spline_help "说明" pos:[250,90] width:35 height:30
GroupBox RTarms "手臂模块" width:290 height:180 pos:[10,140]
edittext pre_arm_name "名称" pos:[30,160] width:250
spinner upperarm_twistjoints "上臂扭曲骨骼" pos:[30,180] width:250 range:[0,100,2] type:#integer
spinner lowerarm_twistjoints "下臂扭曲骨骼" pos:[30,200] width:250 range:[0,100,2] type:#integer
radiobuttons arm_elbow_joints "" labels:#("单肘部关节","双肘部关节") pos:[30,220] columns:2
spinner midarm_twistjoints "中部扭曲骨骼" pos:[30,240] width:250 range:[0,100,2] type:#integer enabled:false
label arm_label01 "" pos:[30,260]
button creatarm "应用手臂" pos:[80,280] width:150 height:30
button arm_load "载入" pos:[20,280] width:35 height:30
button arm_help "说明" pos:[250,280] width:35 height:30
on arm_elbow_joints changed sel do
if sel==2 then midarm_twistjoints.enabled=true else midarm_twistjoints.enabled=false
GroupBox RTlegs "腿部模块" width:290 height:180 pos:[10,330]
edittext pre_leg_name "名称" pos:[30,350] width:250
spinner upperleg_twistjoints "大腿扭曲骨骼" pos:[30,370] width:250 range:[0,100,2] type:#integer
spinner lowerleg_twistjoints "小腿扭曲骨骼" pos:[30,390] width:250 range:[0,100,2] type:#integer
radiobuttons leg_elbow_joints "" labels:#("单膝盖关节","双膝盖关节") pos:[30,410] columns:2
spinner midleg_twistjoints "中部扭曲骨骼" pos:[30,430] width:250 range:[0,100,2] type:#integer enabled:false
label leg_label01 "" pos:[30,450]
button creatleg "应用腿部" pos:[80,470] width:150 height:30
button leg_load "载入" pos:[20,470] width:35 height:30
button leg_help "说明" pos:[250,470] width:35 height:30
on leg_elbow_joints changed sel do
if sel==2 then midleg_twistjoints.enabled=true else midleg_twistjoints.enabled=false
GroupBox RTFKchains "FK链模块(手指,舌头,尾巴,触须等)" width:290 height:170 pos:[10,520]
edittext pre_fkchains_name "名称" pos:[30,540] width:250
spinner fkchains_num "链条数量" pos:[30,560] width:250 range:[0,100,1] type:#integer
spinner fkchains_joints "每条链关节数" pos:[30,580] width:250 range:[0,100,1] type:#integer
label fkchains_label01 "" pos:[30,600]
label fkchains_label02 "" pos:[30,620]
button creatfkchains "应用FK链" pos:[80,650] width:150 height:30
button fkchains_load "载入" pos:[20,650] width:35 height:30
button fkchains_help "说明" pos:[250,650] width:35 height:30
GroupBox RThead "头部模块" width:290 height:140 pos:[10,700]
edittext pre_head_name "名称" pos:[30,720] width:250
checkbox jaw "下巴" pos:[30,740] checked:true
radiobuttons head_twist "" labels:#("X轴扭曲","Y轴扭曲") pos:[30,760] default:1 columns:2
label head_label01 "" pos:[30,780]
button creathead "应用头部" pos:[80,800] width:150 height:30
button head_load "载入" pos:[20,800] width:35 height:30
button head_help "说明" pos:[250,800] width:35 height:30
GroupBox RTlookat "注视模块" width:290 height:150 pos:[10,850]
edittext pre_lookat_name "名称" pos:[30,870] width:250
spinner lookat_joints "关节数量" pos:[30,890] width:250 range:[0,100,1] type:#integer
label lookat_label01 "" pos:[30,910]
label lookat_label02 "" pos:[30,940]
button creatlookat "应用注视" pos:[80,960] width:150 height:30
button lookat_load "载入" pos:[20,960] width:35 height:30
button lookat_help "说明" pos:[250,960] width:35 height:30
)
rollout Advancedmodules "模块高级设置" width:300 height:600
(
local imagespath=#("","","","","","","","","","")
label label01 "----------------覆盖模块颜色------------------"
button ctrlcolor01 "1" width:50 height:20 across:5
button ctrlcolor02 "2" width:50 height:20
button ctrlcolor03 "3" width:50 height:20
button ctrlcolor04 "4" width:50 height:20
button ctrlcolor05 "5" width:50 height:20
button ctrlcolor06 "6" width:50 height:20 across:5
button ctrlcolor07 "7" width:50 height:20
button ctrlcolor08 "8" width:50 height:20
button ctrlcolor09 "9" width:50 height:20
button ctrlcolor10 "10" width:50 height:20
colorPicker thecolor "" color:[255,0,0] modal:false width:280 height:20
label label002 ""
label label003 ""
label label004 "----------------镜像模块------------------"
edittext mirror_modules_name "模块名称" width:240 align:#left across:2
button mirror_modules_load "载入" width:30 align:#right
radiobuttons mirror_LR "" labels:#("对齐左边","对齐右边") default:1 columns:2 align:#center
button mirror_modules_apply "应用模块镜像" width:150 align:#center height:30
label label02 ""
label label03 ""
label label04 "----------------重命名模块------------------"
edittext modules_name "模块新名称" width:240 align:#left across:2
button modules_name_load "载入" width:30 align:#right
button modules_name_apply "应用模块名称" width:150 align:#center height:30
label label05 ""
label label06 ""
label label07 "----------------模块父节点------------------"
edittext modules_parent "新链接模块" width:240 align:#left across:2
button modules_parent_load "载入" width:30 align:#right
button modules_parent_apply "将选定模块链接到新模块" width:150 align:#center height:30
label label08 ""
label label09 ""
label label10 "----------------删除模块------------------"
button modules_delete "删除选定模块" width:150 align:#center height:30
on Advancedmodules open do
(
for i =1 to 10 do imagespath[i]=("C:\Users\ab\Desktop\RigTool\ctrlcolor\\"+ i as string +".png")
ctrlcolor01.images=#(imagespath[1],(bitmap 50 20 color:[0,0,0]),1,1,1,1,1)
ctrlcolor02.images=#(imagespath[2],undefined,1,1,1,1,1)
ctrlcolor03.images=#(imagespath[3],undefined,1,1,1,1,1)
ctrlcolor04.images=#(imagespath[4],undefined,1,1,1,1,1)
ctrlcolor05.images=#(imagespath[5],undefined,1,1,1,1,1)
ctrlcolor06.images=#(imagespath[6],undefined,1,1,1,1,1)
ctrlcolor07.images=#(imagespath[7],undefined,1,1,1,1,1)
ctrlcolor08.images=#(imagespath[8],undefined,1,1,1,1,1)
ctrlcolor09.images=#(imagespath[9],undefined,1,1,1,1,1)
ctrlcolor10.images=#(imagespath[10],undefined,1,1,1,1,1)
)
)
rollout RTctrlrig "生成/删除绑定" width:300 height:600
(
GroupBox creat_ctrlrig "生成绑定" width:290 height:100 pos:[10,10]
checkbox custom_prefix "添加自定义前缀名称" pos:[30,30] checked:false
edittext custom_prefix_name "名称" pos:[30,50] width:250 enabled:false
button create_rig "生成绑定" pos:[80,70] width:150 height:30
GroupBox delete_ctrlrig "删除绑定" width:290 height:100 pos:[10,120]
checkbox delete_bones "是否删除骨骼" pos:[30,150] checked:false
button delete_rig "删除绑定" pos:[80,170] width:150 height:30
on custom_prefix changed thestate do
if custom_prefix.state==true then custom_prefix_name.enabled=true else custom_prefix_name.enabled=false
)
rollout RTctrlsetup "控制器设置" width:300 height:600
(
local imagespath=#("","","","","","","","","","")
label label01 "----------------控制器颜色------------------"
button ctrlcolor01 "1" width:50 height:20 across:5
button ctrlcolor02 "2" width:50 height:20
button ctrlcolor03 "3" width:50 height:20
button ctrlcolor04 "4" width:50 height:20
button ctrlcolor05 "5" width:50 height:20
button ctrlcolor06 "6" width:50 height:20 across:5
button ctrlcolor07 "7" width:50 height:20
button ctrlcolor08 "8" width:50 height:20
button ctrlcolor09 "9" width:50 height:20
button ctrlcolor10 "10" width:50 height:20
colorPicker thecolor "" color:[255,0,0] modal:false width:280 height:20
label label02 ""
label label03 ""
label label04 "----------------控制器缩放------------------"
checkbox x_scale "X轴局部" across:4 align:#left
checkbox y_scale "Y轴局部" align:#center
checkbox z_scale "Z轴局部" align:#center
checkbox mirror_scale "镜像" align:#right
slider scale_parmeter "" ticks:5 range:[0,100,50] type:#integer width:280 align:#center
label label05 "缩放比例:50%" align:#center
button apply_scale "应用缩放" width:150 height:30
on RTctrlsetup open do
(
for i =1 to 10 do imagespath[i]=("C:\Users\ab\Desktop\RigTool\ctrlcolor\\"+ i as string +".png")
ctrlcolor01.images=#(imagespath[1],(bitmap 50 20 color:[0,0,0]),1,1,1,1,1)
ctrlcolor02.images=#(imagespath[2],undefined,1,1,1,1,1)
ctrlcolor03.images=#(imagespath[3],undefined,1,1,1,1,1)
ctrlcolor04.images=#(imagespath[4],undefined,1,1,1,1,1)
ctrlcolor05.images=#(imagespath[5],undefined,1,1,1,1,1)
ctrlcolor06.images=#(imagespath[6],undefined,1,1,1,1,1)
ctrlcolor07.images=#(imagespath[7],undefined,1,1,1,1,1)
ctrlcolor08.images=#(imagespath[8],undefined,1,1,1,1,1)
ctrlcolor09.images=#(imagespath[9],undefined,1,1,1,1,1)
ctrlcolor10.images=#(imagespath[10],undefined,1,1,1,1,1)
)
on scale_parmeter changed val do
(
label05.text=("缩放比例:"+ val as string+"%")
)
on thecolor changed newcolor do selection.wirecolor = newcolor
)
rollout RTctrlselect "选择器" width:300 height:600
(
button btn1 "功能1"
)
rollout RigToolUI "绑定工具" width:700 height:60
(
checkbutton btnsub1 "创建Rig" width:50 height:20 across:5
button btnsub2 "移除左侧" width:70 height:20
button btnsub3 "移除右侧" width:70 height:20
button btnsub4 "打印" width:50 height:20
button btnsub5 "button" width:50 height:20
button btnsub6 "button" width:50 height:20 across:5
button btnsub7 "button" width:50 height:20
button btnsub8 "button" width:50 height:20
button btnsub9 "button" width:50 height:20
button btnsub10 "button" width:50 height:20
subrollout RTleft "" height:600 across:2
subrollout RTright "" height:600 across:2
on btnsub2 pressed do remove_L_rollout()
on btnsub3 pressed do remove_R_rollout()
on btnsub4 pressed do try (print RigToolUI.RTright.Advancedmodules.modules_name.text) catch()
on btnsub1 changed thestate do
if thestate then
(
remove_L_rollout()
remove_R_rollout()
RigToolUI.height +=600
addsubrollout RigToolUI.RTleft NewRig rolledup:false ; append L_rollout NewRig
addsubrollout RigToolUI.RTleft setupmodules rolledup:true ; append L_rollout setupmodules
addsubrollout RigToolUI.RTleft editmodules rolledup:true ; append L_rollout editmodules
addsubrollout RigToolUI.RTleft RTctrlrig rolledup:true ; append L_rollout RTctrlrig
addsubrollout RigToolUI.RTright Advancedmodules rolledup:false ; append R_rollout Advancedmodules
addsubrollout RigToolUI.RTright RTctrlsetup rolledup:true ; append R_rollout RTctrlsetup
)
else (remove_L_rollout() ;remove_R_rollout())
/*
(
removesubrollout RigToolUI.RTleft NewRig
removesubrollout RigToolUI.RTleft setupmodules
removesubrollout RigToolUI.RTleft editmodules
removesubrollout RigToolUI.RTleft RTctrlrig
removesubrollout RigToolUI.RTright Advancedmodules
removesubrollout RigToolUI.RTright RTctrlsetup
)
*/
)
createDialog RigToolUI
+17
View File
@@ -0,0 +1,17 @@
dotnetSunnyUI=dotNet.loadAssembly "D:\Desktop\dll\SunnyUI.dll"
dotnetSunnyCommonUI=dotNet.loadAssembly "D:\Desktop\dll\SunnyUI.Common.dll"
--Create a DotNet Button
mButton = dotNetObject "Sunny.UI.UIbutton"
mButton.text = "Button"
--Create a DotNet Form
hForm = dotNetObject "Sunny.UI.UImainFrame"
hForm.topmost = true
hForm.Style=hForm.Style.green
hForm.show()
showmethods hForm.controls
hForm.controls.Contains mButton
+53
View File
@@ -0,0 +1,53 @@
try(hForm.close())catch()
(
fn whenButtonIsPressed a b =
(
format "Pressed from a DotNet Button\n"
format "Argument a (Form): <%> \n" (classof a)
format "Properties:\n"
showproperties a
format "Methods:\n"
showmethods a
format "Events:\n"
showevents a
format "\nArgument b (Button): <%> \n" (classof b)
format "Properties:\n"
showproperties b
format "Methods:\n"
showmethods a
format "Events:\n"
showevents a
)
--Create a DotNet Form
hForm = dotNetObject "Sunny.UI.UImainFrame"
hForm.topmost = true
--Create a DotNet Button
mButton = dotNetObject "Sunny.UI.UIButton"
mButton.text = "BIG DotNet Button"
mButton.name = "BIG DotNet Button"
mButton.width=230
mButton.height=230
mButton.size = dotNetObject "System.Drawing.Size" 160 160
mButton.location = dotNetObject "System.Drawing.Point" 60 60
--mButton.BringToFront()
nButton = dotNetObject "System.Windows.Forms.Button"
nButton.text = "BIG DotNet Button"
nButton.size = dotNetObject "System.Drawing.Size" 160 160
nButton.location = dotNetObject "System.Drawing.Point" 100 260
--nButton.BringToFront()
--Add an Event Handler for the click event:
--hForm.controls.add mButton --add the Button to the Form
--hForm.controls.add nButton
dotNet.addEventHandler mButton "click" whenButtonIsPressed
--hForm.show() --show the Form with the Button
)
showmethods mButton
hForm.controls.add mButton;mButton.BringToFront()
mButton.SendToBack()
+280
View File
@@ -0,0 +1,280 @@
if TestRollout != undefined do (try(destroydialog TestRollout)catch())
rollout abc "简介" width:300 height:600
(
bitmap bmp1 "Bitmap" pos:[10,10] width:285 height:140 align:#center fileName:("C:\Users\ab\Desktop\RigTool\ctrlcolor\mainabout.png") --bitmap:(bitmap 285 140 color:[255,255,255])
button btn01 "功能1" width:50 height:30 pos:[20,20]
)
rollout def "UI" width:300 height:600
(
edittext edittextbox "编辑框" width:280
--colorPicker thecolor "" color:[0,255,0] modal:false width:350 height:300
on thecolor changed newcolor do selection.wirecolor = newcolor
slider sliderui "滑块" ticks:5 range:[0,100,1] type:#integer
listbox fjfjf "列表盒" item:["1","2"] selection:1 height:2 orient:#horizontal --vertical
pickbutton pickname "拾取按钮"
radiobuttons djfsgkjk "单选" labels:#("1","2")
checkbox mycheckbox "是否选择"
button btn001 "按钮001" width:50 height:20 tooltip:"白色" images:#("C:\Users\ab\Desktop\3.png",undefined,1,1,1,1,1 )
checkbutton mycheckbutton "检查按钮"
dropdownList mydropdownlist "下拉菜单" items:#("1","2","3","4","5","6") height:4
progressBar my_progressbar value:70 color:red across:3
button mybutton "进度条+1"
on btn001 pressed do
(
--format ("name:%s\ncaption:%s\ntext:%s\n" edittext.name edittext.caption edittext.text)
)
on mycheckbox changed thestate do
messageBox ("changed!!!current state is "+mycheckbox.state as string)
on mycheckbox rightclick do
messageBox "the checkbox RightClick!!"
on mycheckbutton changed state do
if state ==on then -- if mycheckbutton.state ==on then
messageBox "checkbutton is on"
else
messageBox "checkbutton is off"
on mydropdownlist selected i do
(
print mydropdownlist.selection
)
on my_progressbar clicked i do
(
print i
my_progressbar.value=i
)
label progressbar_percent_1 ""
label progressbar_percent "%"
on mybutton pressed do
(
print my_progressbar.value
if my_progressbar.value >=100 then
my_progressbar.value=0
else
my_progressbar.value=my_progressbar.value+1
progressbar_percent_1.text=my_progressbar.value as string
)
timer clock "计时器" Interval:1000
local timertick=0
on clock tick do
(
timertick=timertick+1
print timertick
if my_progressbar.value >=100 then
my_progressbar.value=0
else
my_progressbar.value=my_progressbar.value+1
progressbar_percent_1.text=my_progressbar.value as string
if clock.active == true then print "Tick!!"
--clock.active=false --close the timer
)
spinner my_spinner "微调器" range:[0,100,1]
on my_spinner changed i do print i --my_spinner.value
edittext my_edittext "编辑文本" multiline:true height:100 fieldwidth:200
combobox my_combobox "组合框" items:#("1","2","3","4","5") width:60
)
rollout Advancedmodules "模块高级设置工具" width:300 height:600
(
local imagespath=#("","","","","","","","","","")
label label01 "----------------覆盖模块颜色------------------"
button ctrlcolor01 "1" width:50 height:20 across:5
button ctrlcolor02 "2" width:50 height:20
button ctrlcolor03 "3" width:50 height:20
button ctrlcolor04 "4" width:50 height:20
button ctrlcolor05 "5" width:50 height:20
button ctrlcolor06 "6" width:50 height:20 across:5
button ctrlcolor07 "7" width:50 height:20
button ctrlcolor08 "8" width:50 height:20
button ctrlcolor09 "9" width:50 height:20
button ctrlcolor10 "10" width:50 height:20
colorPicker thecolor "" color:[255,0,0] modal:false width:280 height:20
label label02 ""
label label03 ""
label label04 "----------------重命名模块------------------"
edittext modules_name "模块新名称" width:250 align:#center
button modules_name_apply "应用模块名称" width:150 align:#center height:30
label label05 ""
label label06 ""
label label07 "----------------模块父节点------------------"
edittext modules_parent "新链接模块" width:240 align:#left across:2
button modules_parent_load "载入" width:30 align:#right
button modules_parent_apply "将选定模块链接到新模块" width:150 align:#center height:30
label label08 ""
label label09 ""
label label10 "----------------删除模块------------------"
button modules_delete "删除选定模块" width:150 align:#center height:30
on Advancedmodules open do
(
for i =1 to 10 do imagespath[i]=("C:\Users\ab\Desktop\RigTool\ctrlcolor\\"+ i as string +".png")
ctrlcolor01.images=#(imagespath[1],(bitmap 50 20 color:[0,0,0]),1,1,1,1,1)
ctrlcolor02.images=#(imagespath[2],undefined,1,1,1,1,1)
ctrlcolor03.images=#(imagespath[3],undefined,1,1,1,1,1)
ctrlcolor04.images=#(imagespath[4],undefined,1,1,1,1,1)
ctrlcolor05.images=#(imagespath[5],undefined,1,1,1,1,1)
ctrlcolor06.images=#(imagespath[6],undefined,1,1,1,1,1)
ctrlcolor07.images=#(imagespath[7],undefined,1,1,1,1,1)
ctrlcolor08.images=#(imagespath[8],undefined,1,1,1,1,1)
ctrlcolor09.images=#(imagespath[9],undefined,1,1,1,1,1)
ctrlcolor10.images=#(imagespath[10],undefined,1,1,1,1,1)
)
)
rollout RTctrlsetup "控制器设置" width:300 height:600
(
local imagespath=#("","","","","","","","","","")
label label01 "----------------控制器颜色------------------"
button ctrlcolor01 "1" width:50 height:20 across:5
button ctrlcolor02 "2" width:50 height:20
button ctrlcolor03 "3" width:50 height:20
button ctrlcolor04 "4" width:50 height:20
button ctrlcolor05 "5" width:50 height:20
button ctrlcolor06 "6" width:50 height:20 across:5
button ctrlcolor07 "7" width:50 height:20
button ctrlcolor08 "8" width:50 height:20
button ctrlcolor09 "9" width:50 height:20
button ctrlcolor10 "10" width:50 height:20
colorPicker thecolor "" color:[255,0,0] modal:false width:280 height:20
label label02 ""
label label03 ""
label label04 "----------------控制器缩放------------------"
checkbox x_scale "X轴局部" across:4 align:#left
checkbox y_scale "Y轴局部" align:#center
checkbox z_scale "Z轴局部" align:#center
checkbox mirror_scale "镜像" align:#right
slider scale_parmeter "" ticks:5 range:[0,100,50] type:#integer width:280 align:#center
label label05 "缩放比例:50%" align:#center
on RTctrlsetup open do
(
for i =1 to 10 do imagespath[i]=("C:\Users\ab\Desktop\RigTool\ctrlcolor\\"+ i as string +".png")
ctrlcolor01.images=#(imagespath[1],(bitmap 50 20 color:[0,0,0]),1,1,1,1,1)
ctrlcolor02.images=#(imagespath[2],undefined,1,1,1,1,1)
ctrlcolor03.images=#(imagespath[3],undefined,1,1,1,1,1)
ctrlcolor04.images=#(imagespath[4],undefined,1,1,1,1,1)
ctrlcolor05.images=#(imagespath[5],undefined,1,1,1,1,1)
ctrlcolor06.images=#(imagespath[6],undefined,1,1,1,1,1)
ctrlcolor07.images=#(imagespath[7],undefined,1,1,1,1,1)
ctrlcolor08.images=#(imagespath[8],undefined,1,1,1,1,1)
ctrlcolor09.images=#(imagespath[9],undefined,1,1,1,1,1)
ctrlcolor10.images=#(imagespath[10],undefined,1,1,1,1,1)
)
on scale_parmeter changed val do
(
label05.text=("缩放比例:"+ val as string+"%")
)
on thecolor changed newcolor do selection.wirecolor = newcolor
)
rollout TestRollout "Test" width:700 height:60
(
checkbutton btnsub1 "button" width:50 height:20 across:5
button btnsub2 "button" width:50 height:20
button btnsub3 "button" width:50 height:20
button btnsub4 "button" width:50 height:20
button btnsub5 "button" width:50 height:20
button btnsub6 "button" width:50 height:20 across:5
button btnsub7 "button" width:50 height:20
button btnsub8 "button" width:50 height:20
button btnsub9 "button" width:50 height:20
button btnsub10 "button" width:50 height:20
subrollout RTleft "" height:600 across:2
subrollout RTright "" height:600 across:2
on btnsub1 changed thestate do
if thestate then
(
TestRollout.height +=600
addsubrollout TestRollout.RTleft abc
addsubrollout TestRollout.RTleft def
addsubrollout TestRollout.RTright Advancedmodules
addsubrollout TestRollout.RTright RTctrlsetup
)
else
(
TestRollout.height -=600
removesubrollout TestRollout.RTleft abc
removesubrollout TestRollout.RTleft def
removesubrollout TestRollout.RTright Advancedmodules
removesubrollout TestRollout.RTright RTctrlsetup
)
)
createDialog TestRollout
+23
View File
@@ -0,0 +1,23 @@
bipObj = biped.createNew 100 0 [0,0,0] arms:true neckLinks:5\
spineLinks:5 legLinks:4 tailLinks:5 ponyTail1Links:5 \
ponyTail2Links:5 fingers:5 fingerLinks:3 toes:5\
toeLinks:3 ankleAttach:0.3 trianglePelvis:True \
prop1Exists:True prop2Exists:True prop3Exists:True \
forearmTwistLinks:4
nn = biped.maxNumNodes bipObj
nl = biped.maxNumLinks bipObj
for i = 1 to nn do
(
anode = biped.getNode bipObj i
if anode != undefined do
(
format "% :\t%\n" i anode.name
for j = 1 to nl do
(
alink = biped.getNode bipObj i link:j
if alink != undefined do
format "% : % \t%\n" i j alink.name
)
)
)
+116
View File
@@ -0,0 +1,116 @@
if abc !=undefined then DestroyDialog abc
rollout abc "DotNet控件 UI" height:1000 width:830
(
button a "showProperties()显示属性" width:230 height:30 across:3
button b "showMethods()显示方法(调用函数)" width:230 height:30
button c "showevents()显示事件" width:230 height:30
button d "getProperty()获取属性值" width:230 height:30 across:3
button e "setProperty()设置属性值" width:230 height:30
button f "getpropnames()控件每个属性(数组)" width:230 height:30
----------------------------------------------------------------------------------------------------------------------------------
dotNetControl dotnetdatagrid "datagridview" width:800 height:300
dotNetControl dotnetdatagridview "datagridview" width:800 height:300 --不是经典的datagrid
dotNetControl dotnettreeview "treeview" width:800 height:300
----------------------------------------------------------------------------------------------------------------------------------
on a pressed do
(
showProperties dotnetdatagridview --显示属性
)
on b pressed do
(
showMethods dotnetdatagridview --显示方法(即可调用的函数)
)
on c pressed do
(
showevents dotnetdatagridview -- 显示控件可调用的事件
)
on d pressed do
(
format "获取到的属性值:%\n" (getProperty dotnetdatagridview "text" asdotnetobject:false) --获取名为text属性的值
)
on e pressed do
(
format "设置成的属性值:%\n" (setProperty dotnetdatagridview "text" "dotnet形式表格") --设置名为text属性的值为"dotnet按钮"
)
on f pressed do
(
print (getpropnames dotnetdatagridview) --控件的所有属性,输出为一个数组
)
--------------------------------------------------------------------------------------------------------------------------------
-- on dotnetbtn click do print "点击了一次dotnet按钮"
-- on dotnetbtn mousedown do print "鼠标进入dotnet按钮范围"
on abc open do
(
for i =1 to 5 do dotnetdatagrid.columns.add ("column"+i as string) ("列 "+i as string)
dotnetdatagrid.RowCount=4
dotnetdatagrid.rows.item[3].cells.item[3].value = "举例dotnetdatagrid"
for i =1 to 5 do dotnetdatagridview.columns.add ("column"+i as string) ("列 "+i as string)
dotnetdatagridview.rows.add 4
dotnetdatagridview.rows.item[3].cells.item[3].value = "举例"
dotnettreeview.CheckBoxes=true
treenode01=dotnettreeview.Nodes.add "树干1"
treenode02=dotnettreeview.Nodes.add "树干2"
treenode03=dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干48543"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干35485"
dotnettreeview.Nodes.add "树干16543"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干3"
dotnettreeview.Nodes.add "树干1788fgsd3"
for i=1 to 100 do
(
ndstext=("node"+i as string)
nds=treenode01.nodes.add ndstext
treenode01=nds
)
treenode04=treenode01.Nodes.add "树叶1"
treenode05=dotnettreeview.nodes.item[1].nodes.add "12"
treenode06=dotnettreeview.nodes.item[1].nodes.item[0].nodes.add "34"
format "全路径是:%\n" treenode06.FullPath
format "父级叶名称是:%\n" treenode06.parent.text
dotnettreeview.SelectedNode
)
on dotnettreeview AfterSelect do print dotnettreeview.SelectedNode.FullPath
)
CreateDialog abc
if abc.dotnettreeview.SelectedNode !=undefined then format "当前选择:%\n" abc.dotnettreeview.SelectedNode.FullPath
showevents abc.dotnettreeview
+130
View File
@@ -0,0 +1,130 @@
clearListener ()
try( hForm.close() )catch()
dotnet.loadAssembly "D:\\Desktop\\dll\\SunnyUI.Common.dll"
dotnet.loadAssembly "D:\\Desktop\\dll\\SunnyUI.dll"
fn whenButtonIsPressed =
(
print "button01"
)
fn whenNavIsPressed a b=
(
print(classof b)
)
uiNavbar1=dotNetObject "Sunny.UI.UINavbar"
uiNavbar1.nodes.add("¿Ø¼þ")
--Create a DotNet Button
mButton = dotNetObject "Sunny.UI.UIbutton"
mButton.text = "mButton"
mButton.size = dotNetObject "System.Drawing.Size" 160 80
mButton.location = dotNetObject "System.Drawing.Point" 160 0
page1001Button = dotNetObject "Sunny.UI.UIbutton"
page1001Button.text = "page1001 Button"
page1001Button.size = dotNetObject "System.Drawing.Size" 160 80
page1001Button.location = dotNetObject "System.Drawing.Point" 0 0
page1002Button = dotNetObject "Sunny.UI.UIbutton"
page1002Button.text = "page1002 Button"
page1002Button.size = dotNetObject "System.Drawing.Size" 160 80
page1002Button.location = dotNetObject "System.Drawing.Point" 0 0
--Create a DotNet Form
hForm = dotNetObject "Sunny.UI.UIform"
--Create a DotNet page
hpage1001 = dotNetObject "Sunny.UI.UIpage"
hpage1001.AutoScaleMode=hpage1001.AutoScaleMode.none
hpage1001.PageIndex=1001
UIlabel1001=dotNetObject "Sunny.UI.UIlabel"
UIlabel1001.text="Page 1001"
UIlabel1001.location = dotNetObject "System.Drawing.Point" 0 200
UIlabel1001.ForeColor=(dotnetclass "System.Drawing.Color").FromArgb 255 0 255 255
hpage1001.text="page 1"
hpage1001.BackColor=(dotnetclass "System.Drawing.Color").FromArgb 255 0 0 0
hpage1002 = dotNetObject "Sunny.UI.UIpage"
hpage1002.AutoScaleMode=hpage1002.AutoScaleMode.none
hpage1002.text="page 2"
hpage1002.PageIndex=1002
--Create a DotNet uitablecontrol
htab = dotNetObject "Sunny.UI.UITabControl"
htab.size = dotNetObject "System.Drawing.Size" 30 30
htab.location = dotNetObject "System.Drawing.Point" 160 150
hForm.topmost = true
hForm.text="UIform"
hForm.AutoScaleMode=hForm.AutoScaleMode.none
hForm.ShowDragStretch =true
hForm.BackColor=(dotnetclass "System.Drawing.Color").FromArgb 255 255 255 255
--add controls
hForm.controls.add mButton
hForm.controls.add UIlabel1001
hForm.controls.add page1001Button
hForm.controls.add page1002Button
hForm.controls.add uiNavbar1
hForm.controls.add htab
hForm.AddPage hpage1001
hForm.SelectPage 1001
hForm.AddPage hpage1002
hForm.SelectPage 1002
hForm.MainTabControl=htab
--change the style
--Add an Event Handler for the click event
dotNet.addEventHandler mButton "click" whenButtonIsPressed
page1001Button.parent=hpage1001
page1002Button.parent=hpage1002
UIlabel1001.parent=hpage1001
hForm.show() --show the Form with the Button
/*
showproperties hForm
show aside
showevents mButton
dotnet.showConstructors mButton
hForm.Region
hForm.controls.count
hForm.controls.item[0]
createDialog (dotNetObject "Sunny.UI.UIMessageDialog")
*/
/*
AsideHeaderMain = dotNetObject "Sunny.UI.UIAsideHeaderMainFrame"
--AsideHeaderMain.controls.clear()
AsideHeaderMain.show()
AsideHeaderMain.controls.count
--AsideHeaderMain.controls.item[0].backcolor=(dotnetclass "System.Drawing.Color").FromArgb 255 255 0 255
--AsideHeaderMain.controls.item[1].backcolor=(dotnetclass "System.Drawing.Color").FromArgb 255 0 255 255
--AsideHeaderMain.controls.item[2].backcolor=(dotnetclass "System.Drawing.Color").FromArgb 255 255 255 0
for i=0 to AsideHeaderMain.controls.count-1 do AsideHeaderMain.controls.item[i].BringToFront()
AsideHeaderMain.AddPage (dotNetObject "Sunny.UI.UIPage")
AsideHeaderMain.AddPage (dotNetObject "Sunny.UI.UIPage")
showmethods AsideHeaderMain
*/
+83
View File
@@ -0,0 +1,83 @@
if abc !=undefined then DestroyDialog abc
rollout abc "DotNet控件 UI" height:800 width:830
(
button a "showProperties()显示属性" width:230 height:30 pos:[0,0]
button b "showMethods()显示方法(调用函数)" width:230 height:30 pos:[0,40]
button c "showevents()显示事件" width:230 height:30 pos:[0,80]
button d "getProperty()获取属性值" width:230 height:30 pos:[0,120]
button e "setProperty()设置属性值" width:230 height:30 pos:[0,160]
button f "getpropnames()控件每个属性(数组)" width:230 height:30 pos:[0,200]
----------------------------------------------------------------------------------------------------------------------------------
dotNetControl dotnetbtn "button" height:50 width:230 pos:[0,240]
dotNetControl dotnetcalender "monthcalendar" height:180 width:280 pos:[0,300]
dotNetControl dotnettext "label" width:230 pos:[0,500]
dotNetControl dotnetlist "listbox" width:230 height:80 pos:[0,530]
dotNetControl dotnetdatagrid "datagrid" width:230 height:160 pos:[0,620]
dotNetControl dotnetpicturebox "picturebox" width:230 height:150 pos:[300,0]
dotNetControl dotnetprogressbar "progressbar" width:230 height:20 pos:[300,180]
dotNetControl dotnetcombobox "combobox" width:230 height:100 pos:[300,220]
dotNetControl dotnetcheckedlistbox "checkedlistbox" width:230 height:100 pos:[300,340]
dotNetControl dotnettrackbar "trackbar" width:230 height:50 pos:[300,460]
dotNetControl dotnetcheckbox "checkbox" width:230 height:30 pos:[300,510]
dotNetControl dotnettextbox "textbox" width:230 height:20 pos:[300,550]
dotNetControl dotnetrichtextbox "richtextbox" width:230 height:210 pos:[300,580]
dotNetControl dotnetNumericUpDown "NumericUpDown" width:230 height:20 pos:[600,0]
dotNetControl dotnetgroupbox "groupbox" width:230 height:100 pos:[600,40]
dotNetControl dotnetradiobutton "radiobutton" width:230 height:20 pos:[600,160]
dotNetControl dotnetvscrollbar "vscrollbar" width:20 height:200 pos:[600,200]
dotNetControl dotnethscrollbar "hscrollbar" width:230 height:20 pos:[600,410]
dotNetControl dotnettreeview "treeview" width:230 height:340 pos:[600,450]
----------------------------------------------------------------------------------------------------------------------------------
on a pressed do
(
showProperties dotnethscrollbar --显示属性
)
on b pressed do
(
showMethods dotnetbtn --显示方法(即可调用的函数)
)
on c pressed do
(
showevents dotnetbtn -- 显示控件可调用的事件
)
on d pressed do
(
format "获取到的属性值:%\n" (getProperty dotnetbtn "text" asdotnetobject:false) --获取名为text属性的值
)
on e pressed do
(
format "设置成的属性值:%\n" (setProperty dotnetbtn "text" "dotnet形式的按钮") --设置名为text属性的值为"dotnet按钮"
)
on f pressed do
(
print (getpropnames dotnetbtn) --控件的所有属性,输出为一个数组
)
--------------------------------------------------------------------------------------------------------------------------------
on dotnetbtn click do print "点击了一次dotnet按钮"
on dotnetbtn mousedown do print "鼠标进入dotnet按钮范围"
on abc open do
(
dotnetbtn.text="dotnet按钮"
dotnettext.text="dotnet标签"
dotnetprogressbar.value=50
dotnetcheckbox.text="check按钮"
dotnettextbox.text="textbox(单行)"
dotnetrichtextbox.text="richtextbox(多行)"
dotnetvscrollbar.value=20
dotnethscrollbar.value=80
)
)
CreateDialog abc
+21
View File
@@ -0,0 +1,21 @@
--files = #("C:\Users\ab\Desktop\00000.jpg","C:\Users\ab\Desktop\00001.jpg")
files=#()
for i=0 to 127 do append files ("D:\Bip动作库\3dsmax\九尾狐\jiuwei_renxing_show\\"+i as string +".jpg")
GifFullPath = "C:\Users\ab\Desktop\mygif.gif"
gifwidth=400
gifheight=224
fps=30
ColorTolerance=1 --色差,数值约低质量越好
GifCreator = dotnetclass "RefPlayer.GifCreator"
GifCreator.Init fps ColorTolerance
dotNet.removeAllEventHandlers GifCreator
GifCreator.Start files GifFullPath gifwidth gifheight --不要宽高参数,则图片默认大小
showMethods GifCreator
+23
View File
@@ -0,0 +1,23 @@
/*
--IKSys.ikChain $Bone035 $Bone037 IKLimb
IKSys.solverCount() --返回系统安装的可用ik求解器数
IKSys.solverName 1 --返回索引求解器字符串名称 hi结算器
IKSys.solverName 2 -- iklimb肢体结算器
IKSys.solverName 3 -- spline ik结算器
IKSys.solverUIName 2 --返回索引求解器ui名称
*/
--a=IKSys.ikChain $Bone035 $Bone037 (IKSys.solverName 2) --使用肢体求解器
--classOf a
--showClass "IK_Chain_Object"
--showProperties $
--showProperties $.pos.controller
--classOf $
--superClassOf $
--getPropNames $
--show $
--show $.transform.controller
$.transform.controller.VHTarget
$.pos
@@ -0,0 +1,15 @@
--SetINISetting <文件路径> <节> <键> <键值>
--例如:
--[CopyPaste1]
--nombredobjetselectionnay1=1
--nombredobjetselectionnay1
a="100"
SetINISetting "C:\Users\ab\Desktop\YWB_config.ini" "CopyPaste1" "nombredobjetselectionnay1" (selection.count as string)
SetINISetting "C:\Users\ab\Desktop\YWB_config.ini" "hello" "world" a --写入键值
--delINISetting "C:\Users\ab\Desktop\YWB_config.ini" "hello" "world" --删除键
--delINISetting "C:\Users\ab\Desktop\YWB_config.ini" "hello" --删除节和键值
world=getINISetting "C:\Users\ab\Desktop\YWB_config.ini" "CopyPaste1" "nombredobjetselectionnay1" --读取键值
hasINISetting "C:\Users\ab\Desktop\YWB_config.ini" "CopyPaste1" "nombredobjetselectionnay1" --如果存在,则返回true
format "world=%\n" world
+3
View File
@@ -0,0 +1,3 @@
--saveMaxFile "D:\ttt.max" --usenewfile:true
archiveMaxFile "C:\Users\ab\Desktop\1\wuxia" quiet:false --2019以及更高版本可用
+42
View File
@@ -0,0 +1,42 @@
if testtest != undefined do (try(destroydialog testtest)catch())
rcMenu myrcMenu
(
menuItem item1 "item1"
menuItem item2 "item2" checked:true
separator line1
submenu "submenu"
(
menuItem subitem1 "subitem1"
menuItem subitem2 "subitem2"
menuItem subitem3 "subitem3"
)
menuItem item3 "item3"
menuItem item4 "item4"
menuItem item5 "item5"
on item1 picked do item1.checked=true
on item2 picked do item2.checked=true
on item3 picked do item3.checked=true
on subitem1 picked do subitem1.checked=true
on myrcMenu open do print "open myremenu"
)
rollout testtest "test" width:400 height:300
(
button btn1 "rcmenu" width:80 height:80
on btn1 rightclick do popUpMenu myrcMenu align:#align_topleft
)
CreateDialog testtest
+114
View File
@@ -0,0 +1,114 @@
--$Sphere001.position=random [0,0,0][100,100,100]
--$Sphere001.position.x=random 0 100
--$Sphere001.transform=random [0,0,0][100,100,100]
--$Sphere001.rotation=random [0,0,0][100,100,100]
/*
format "$Sphere001.transform=%\n" $Sphere001.transform --世界位置,旋转,缩放
format "$Sphere001.rotation=%\n" $Sphere001.rotation --世界旋转(四元数)
format "$Sphere001.position=%\n" $Sphere001.position --世界位置
format "$Sphere001.scale=%\n" $Sphere001.scale --世界缩放
format "$Sphere001.pivot=%\n" $Sphere001.pivot --轴点
--默认控制器下世界坐标
$Sphere003.position.controller.'X 位置' --英文版为 $Sphere003.position.controller.'X Position'
$Sphere003.rotation.controller.'X 轴旋转'=0 --英文版为 $Sphere003.rotation.controller.'X Rotation'
$Sphere003.scale.x --中英文一致
--旋转四元数 x y z w X、Y、Z构成矢量,W是围绕矢量的旋转角度
$Sphere003.rotation = $Sphere001.rotation
$Sphere003.rotation.x
$Sphere003.rotation.y
$Sphere003.rotation.z
$Sphere003.rotation.w
*/
/*a=point()
a.transform=$.transform
b=point()
b.transform=$.children[1].transform
a.size=10
a.box=true
a.cross=false
b.size=10
b.box=true
b.cross=false
$.pos.controller = position_constraint()
$.pos.controller.appendtarget a 100
$.rotation.controller = lookat_constraint()
$.rotation.controller.appendtarget b 100
$.rotation.controller.lookat_vector_length = 0
$.rotation.controller.viewline_length_abs = off
$.rotation.controller.upnode_world = off --上方向节点设置
$.rotation.controller.pickupnode = b
$.rotation.controller.relative = on --保持初始偏移
$.children[1].pos.controller = position_constraint()
$.children[1].pos.controller.appendtarget b 100
$.boneScaleType=#none
$.scale.controller = ScaleXYZ()
$.scale.controller.X_Scale.controller = float_script()
--骨骼链条生成
rollout boneRig "请先选中根骨"
(
button btn "骨链绑定"
on btn pressed do (
bo = $ --选中的骨骼节点
a = point() --已经在骨骼节点处创建的虚拟节点
a.size=10
a.cross=false
a.box=true
a.transform = bo.transform
while bo.children[1]!=null do (
bo.pos.controller = position_constraint() --先位置约束到已创建的a
bo.pos.controller.appendtarget a 100
bo.boneScaleType=#none --更正缩放控制
bo.scale.controller = ScaleXYZ()
bo.scale.controller.X_Scale.controller = float_script()
a = point() --为子端创建一个新节点
a.size=10
a.cross=false
a.box=true
a.transform = bo.children[1].transform --对齐到子端
bo.rotation.controller = lookat_constraint() --骨骼注视约束到子端的a
bo.rotation.controller.appendtarget a 100
bo.rotation.controller.lookat_vector_length = 0
bo.rotation.controller.viewline_length_abs = off
bo.rotation.controller.upnode_world = off --上方向节点设置
bo.rotation.controller.pickupnode = a
bo.rotation.controller.relative = on --保持初始偏移
bo = bo.children[1] --递进bo赋值为子骨骼
)
bo.pos.controller = position_constraint() --末端子骨骼位置约束
bo.pos.controller.appendtarget a 100
)
)
createdialog boneRig
*/
+101
View File
@@ -0,0 +1,101 @@
if rollouttest != undefined then
try(
cui.unRegisterDialogBar rollouttest
DestroyDialog rollouttest
)catch()
rollout subrollouttest "rollouttest"
(
button btn01 "左侧" width:80 height:30 across:2
button btn02 "右侧" width:80 height:30
button btn03 "左侧" width:80 height:30 across:2
button btn04 "右侧" width:80 height:30
button btn05 "左侧" width:80 height:30 across:2
button btn06 "右侧" width:80 height:30
button btn07 "左侧" width:80 height:30 across:2
button btn08 "右侧" width:80 height:30
button btn09 "左侧" width:80 height:30 across:2
button btn10 "右侧" width:80 height:30
button btn11 "左侧" width:80 height:30 across:2
button btn12 "右侧" width:80 height:30
button btn13 "左侧" width:80 height:30 across:2
button btn14 "右侧" width:80 height:30
button btn15 "左侧" width:80 height:30 across:2
button btn16 "右侧" width:80 height:30
button btn17 "左侧" width:80 height:30 across:2
button btn18 "右侧" width:80 height:30
button btn19 "左侧" width:80 height:30 across:2
button btn20 "右侧" width:80 height:30
)
rollout subrollouttest02 "rollouttest02" width:200
(
button btn01 "左侧" width:80 height:30 across:2
button btn02 "右侧" width:80 height:30
button btn03 "左侧" width:80 height:30 across:2
button btn04 "右侧" width:80 height:30
button btn05 "左侧" width:80 height:30 across:2
button btn06 "右侧" width:80 height:30
button btn07 "左侧" width:80 height:30 across:2
button btn08 "右侧" width:80 height:30
button btn09 "左侧" width:80 height:30 across:2
button btn10 "右侧" width:80 height:30
button btn11 "左侧" width:80 height:30 across:2
button btn12 "右侧" width:80 height:30
button btn13 "左侧" width:80 height:30 across:2
button btn14 "右侧" width:80 height:30
button btn15 "左侧" width:80 height:30 across:2
button btn16 "右侧" width:80 height:30
button btn17 "左侧" width:80 height:30 across:2
button btn18 "右侧" width:80 height:30
button btn19 "左侧" width:80 height:30 across:2
button btn20 "右侧" width:80 height:30
)
rollout subrollouttest03 "rollouttest03" width:200
(
button btn01 "左侧" width:80 height:30 across:2
button btn02 "右侧" width:80 height:30
button btn03 "左侧" width:80 height:30 across:2
button btn04 "右侧" width:80 height:30
button btn05 "左侧" width:80 height:30 across:2
button btn06 "右侧" width:80 height:30
button btn07 "左侧" width:80 height:30 across:2
button btn08 "右侧" width:80 height:30
button btn09 "左侧" width:80 height:30 across:2
button btn10 "右侧" width:80 height:30
button btn11 "左侧" width:80 height:30 across:2
button btn12 "右侧" width:80 height:30
button btn13 "左侧" width:80 height:30 across:2
button btn14 "右侧" width:80 height:30
button btn15 "左侧" width:80 height:30 across:2
button btn16 "右侧" width:80 height:30
button btn17 "左侧" width:80 height:30 across:2
button btn18 "右侧" width:80 height:30
button btn19 "左侧" width:80 height:30 across:2
button btn20 "右侧" width:80 height:30
)
rollout rollouttest "rollouttest" width:300
(
button btn01 "左侧" width:80 height:30 across:3
button btn02 "右侧" width:80 height:30
button btn05 "浮动" width:80 height:30
button btn06 "功能" width:80 height:30
subrollout RTleft "" width:280 height:650
on btn01 pressed do cui.dockDialogBar rollouttest #cui_dock_left
on btn02 pressed do cui.dockDialogBar rollouttest #cui_dock_right
on btn05 pressed do cui.floatDialogBar rollouttest
on btn06 pressed do print (cui.getDockState rollouttest)
)
CreateDialog rollouttest
cui.registerDialogBar rollouttest style:#(#cui_dock_vert,#cui_floatable)
cui.dockDialogBar rollouttest #cui_dock_left
addsubrollout rollouttest.RTleft subrollouttest
addsubrollout rollouttest.RTleft subrollouttest02 rolledup:true
addsubrollout rollouttest.RTleft subrollouttest03 rolledup:true
+37
View File
@@ -0,0 +1,37 @@
globel FBX_convert_str.ConverterFloater
rollout UImenu "1" width:300 height:150
(
GroupBox thegroupbox "工具组1" height:40 offset:[0,0] width:280
)
rollout UImenu2 "2" width:300 height:300
(
GroupBox thegroupbox1 "工具组2" height:40 offset:[0,0] width:280
)
rollout UImenu3 "3" width:300 height:300
(
GroupBox thegroupbox1 "工具组2" height:40 offset:[0,0] width:280
)
function MakerolloutFloat =
(
FBX_convert_str.ConverterFloater = newRolloutFloater "工具名称" 325 500
addRollout UImenu FBX_convert_str.ConverterFloater rolledup:false
addRollout UImenu2 FBX_convert_str.ConverterFloater rolledup:false
closeRolloutFloater FBX_convert_str.ConverterFloater
removeRollout UImenu2
)
MakerolloutFloat()
+19
View File
@@ -0,0 +1,19 @@
ImageFileName = "C:\Users\ab\Desktop\2.jpg"
SaveFormat = (DotNetClass "System.Drawing.Imaging.ImageFormat").jpeg --ÓÐpng bmp gif icon tiff jpeg µÈµÈ³£Óøñʽ
start_posX=-1157
start_posY=288
picwidth=800
picheight=400
leftright_offset=0
updown_offset=0
ScreenBitmap = dotnetobject "System.Drawing.Bitmap" picwidth picheight (dotnetclass "System.Drawing.Imaging.PixelFormat").Format32bppPArgb
Graphics = (dotnetclass "System.Drawing.Graphics").FromImage ScreenBitmap
Graphics.CopyFromScreen start_posX start_posY leftright_offset updown_offset ScreenBitmap.Size (dotnetclass "System.Drawing.CopyPixelOperation").SourceCopy
ScreenBitmap.Save ImageFileName SaveFormat
+24
View File
@@ -0,0 +1,24 @@
/*
--×ÀÃæ²¶×½
ssBitmap1 = windows.snapshot 0
--display ssBitmap1 caption:"Desktop Snapshot"
ssBitmap1.filename = "C:\Users\ab\Desktop\desktop.jpg"
save ssBitmap1
--maxÖ÷´°¿Ú
ssBitmap2 = windows.snapshot #max
--display ssBitmap2 caption:"3ds Max Main Window"
ssBitmap2.filename = "C:\Users\ab\Desktop\max.jpg"
save ssBitmap2
--µ±Ç°ÊÓ¿Ú
ssBitmap3 = windows.snapshot (viewport.getHWnd())
--display ssBitmap3 caption:"Active Viewport"
ssBitmap3.filename = "C:\Users\ab\Desktop\viewport.jpg"
save ssBitmap3
*/
ssBitmap4 = windows.snapshot 0 capturescreenpixels:true
display ssBitmap4 caption:"Active Viewport"
-- ssBitmap4.filename = "C:\Users\ab\Desktop\screenpiexls.jpg"
-- save ssBitmap4
+81
View File
@@ -0,0 +1,81 @@
/*
--//对齐旋转
a=$box003
b=$box002
*/
--//不建议使用这种写法
--a.rotation = b.rotation
--//建议使用这种写法
/*
a.rotation.x_rotation = b.rotation.x_rotation
a.rotation.y_rotation = b.rotation.y_rotation
a.rotation.z_rotation = b.rotation.z_rotation
*/
--//镜像旋转 --仅适用于本身对称物体
Fn XPosMirror yuanlai mubiao SY_index =
(
local OriginalEuler,TargetController,TargetEuler
OriginalEuler = yuanlai.Rotation.Controller.Value as EulerAngles
TargetEuler = Copy OriginalEuler
TargetController = mubiao.Rotation.Controller
case SY_index of
(
1:
(
TargetEuler.X *= -1
TargetEuler.Z *= -1
TargetEuler.Z += 180.0
)
2:
(
TargetEuler.X *= -1
TargetEuler.Z *= -1
)
3:
(
TargetEuler.X *= -1
TargetEuler.Z *= -1
TargetEuler.Z *= -1
TargetEuler.Y += 180.0
TargetEuler.Z += 180.0
)
default:
(
TargetEuler.X *= -1
TargetEuler.Z *= -1
TargetEuler.Z += 180.0
)
)
TargetController.Value = TargetEuler as quat
)
a=$
a.pivot
b=copy a
b.pos.x *= -1 ; XPosMirror a b 1
/*
a=b
b=copy a
b.pos.y *= -1 ; XPosMirror a b 2
a=b
b=copy a
b.pos.z *= -1 ; XPosMirror a b 3
*/
+102
View File
@@ -0,0 +1,102 @@
if rollouttest != undefined then
try(
cui.unRegisterDialogBar rollouttest
DestroyDialog rollouttest
)catch()
rollout subrollouttest "rollouttest"
(
button btn01 "左侧" width:80 height:30 across:2
button btn02 "右侧" width:80 height:30
button btn03 "左侧" width:80 height:30 across:2
button btn04 "右侧" width:80 height:30
button btn05 "左侧" width:80 height:30 across:2
button btn06 "右侧" width:80 height:30
button btn07 "左侧" width:80 height:30 across:2
button btn08 "右侧" width:80 height:30
button btn09 "左侧" width:80 height:30 across:2
button btn10 "右侧" width:80 height:30
button btn11 "左侧" width:80 height:30 across:2
button btn12 "右侧" width:80 height:30
button btn13 "左侧" width:80 height:30 across:2
button btn14 "右侧" width:80 height:30
button btn15 "左侧" width:80 height:30 across:2
button btn16 "右侧" width:80 height:30
button btn17 "左侧" width:80 height:30 across:2
button btn18 "右侧" width:80 height:30
button btn19 "左侧" width:80 height:30 across:2
button btn20 "右侧" width:80 height:30
)
rollout subrollouttest02 "rollouttest02" width:200
(
button btn01 "左侧" width:80 height:30 across:2
button btn02 "右侧" width:80 height:30
button btn03 "左侧" width:80 height:30 across:2
button btn04 "右侧" width:80 height:30
button btn05 "左侧" width:80 height:30 across:2
button btn06 "右侧" width:80 height:30
button btn07 "左侧" width:80 height:30 across:2
button btn08 "右侧" width:80 height:30
button btn09 "左侧" width:80 height:30 across:2
button btn10 "右侧" width:80 height:30
button btn11 "左侧" width:80 height:30 across:2
button btn12 "右侧" width:80 height:30
button btn13 "左侧" width:80 height:30 across:2
button btn14 "右侧" width:80 height:30
button btn15 "左侧" width:80 height:30 across:2
button btn16 "右侧" width:80 height:30
button btn17 "左侧" width:80 height:30 across:2
button btn18 "右侧" width:80 height:30
button btn19 "左侧" width:80 height:30 across:2
button btn20 "右侧" width:80 height:30
)
rollout subrollouttest03 "rollouttest03" width:200
(
button btn01 "左侧" width:80 height:30 across:2
button btn02 "右侧" width:80 height:30
button btn03 "左侧" width:80 height:30 across:2
button btn04 "右侧" width:80 height:30
button btn05 "左侧" width:80 height:30 across:2
button btn06 "右侧" width:80 height:30
button btn07 "左侧" width:80 height:30 across:2
button btn08 "右侧" width:80 height:30
button btn09 "左侧" width:80 height:30 across:2
button btn10 "右侧" width:80 height:30
button btn11 "左侧" width:80 height:30 across:2
button btn12 "右侧" width:80 height:30
button btn13 "左侧" width:80 height:30 across:2
button btn14 "右侧" width:80 height:30
button btn15 "左侧" width:80 height:30 across:2
button btn16 "右侧" width:80 height:30
button btn17 "左侧" width:80 height:30 across:2
button btn18 "右侧" width:80 height:30
button btn19 "左侧" width:80 height:30 across:2
button btn20 "右侧" width:80 height:30
)
rollout rollouttest "rollout测试" width:300
(
button btn01 "左侧" width:80 height:30 across:3
button btn02 "右侧" width:80 height:30
button btn05 "浮动" width:80 height:30
button btn06 "功能" width:80 height:30
subrollout RTleft "" width:280 height:650
on btn01 pressed do cui.dockDialogBar rollouttest #cui_dock_left
on btn02 pressed do cui.dockDialogBar rollouttest #cui_dock_right
on btn05 pressed do cui.floatDialogBar rollouttest
on btn06 pressed do print (cui.getDockState rollouttest)
)
CreateDialog rollouttest
cui.registerDialogBar rollouttest style:#(#cui_dock_all,#cui_floatable)
cui.dockDialogBar rollouttest #cui_dock_left
addsubrollout rollouttest.RTleft subrollouttest
addsubrollout rollouttest.RTleft subrollouttest02 rolledup:true
addsubrollout rollouttest.RTleft subrollouttest03 rolledup:true
+28
View File
@@ -0,0 +1,28 @@
if rollouttest != undefined then
try(
cui.unRegisterDialogBar rollouttest
DestroyDialog rollouttest
)catch()
rollout rollouttest "rollouttest" width:200
(
button btn01 "左侧" width:80 height:30
button btn02 "右侧" width:80 height:30
button btn03 "上侧" width:80 height:30
button btn04 "下侧" width:80 height:30
button btn05 "浮动" width:80 height:30
button btn06 "功能" width:80 height:30
on btn01 pressed do cui.dockDialogBar rollouttest #cui_dock_left
on btn02 pressed do cui.dockDialogBar rollouttest #cui_dock_right
on btn03 pressed do cui.dockDialogBar rollouttest #cui_dock_top
on btn04 pressed do cui.dockDialogBar rollouttest #cui_dock_bottom
on btn05 pressed do cui.floatDialogBar rollouttest
on btn06 pressed do print (cui.getDockState rollouttest)
)
CreateDialog rollouttest
cui.registerDialogBar rollouttest style:#(#cui_dock_all,#cui_floatable)
+6
View File
@@ -0,0 +1,6 @@
localTime --"2022/9/27 9:35:42"
execute ("2022") --2022
filterString "2022/9/27 9:35:42" "/" --#("2022", "9", "27 9:35:42")
timeStamp() --返回当日000起所经历的毫秒数
getLocalTime() --#(2022, 9, 2, 27, 9, 40, 20, 612) 年月星期日小时分钟秒毫秒
getUniversalTime() --#(2022, 9, 2, 27, 1, 42, 22, 727) 返回协调世界时间UTC
+31
View File
@@ -0,0 +1,31 @@
--paramWire.start() --视口中选择了一个对象时才可以用,作用是启动参数连接
--paramWire.openEditor() --打开参数连接管理器
--paramWire.editParams $box001.baseobject[#width] $box002.baseobject[#height] --打开左右指定参数连接管理器
--paramWire.editParam $box001.baseobject[#width] --仅打开左侧指定参数参数管理器
--paramWire.editParam $box001.baseobject[#width] --访问对象本身属性width
--paramWire.editParam $box001.bend[#angle] --访问对象修改器属性angle
--paramWire.editParam $box001[#transform][#position][#x_position]--访问对象变换属性pos.x
--paramWire.Connect $box001.baseobject[#width] $box002.baseobject[#height] "宽度*2" --单项左连接右属性
--paramWire.Connect $box001[#transform][#position][#x_position] $box002[#transform][#position][#x_position] "x_位置+100" --单项左连接右属性
--paramWire.disconnect $box002.height.controller
--//注意:断开的是被控制的属性,不是主动控制属性
--paramWire.disconnect $box002.position.controller[1]
--paramWire.connect2Way $box001.baseobject[#length] $box002.baseobject[#length] "长度*2" "长度*2"
--双向连接左右属性,注意,右属性对左属性的影响会使左属性重新刷新,故尽量单项连接
--paramWire.connect2Way $box001[#transform][#position][#x_position] $box002[#transform][#position][#x_position] "x_位置+100" "x_位置-100" --单项左连接右属性
--paramWire.disconnect2Way $box001.position.controller[1] $box002.position.controller[1]
--断开双向连接左右属性
--//注意:单向连接和双向连接不同,不可互相混用
+49
View File
@@ -0,0 +1,49 @@
global bywn=#()
global cywn=1
global btnname="ÕâÊÇÒ»¸ö°´Å¥mac..."
callbacks.removeScripts #selectionSetChanged id:#Rollout
fn xianshi=
(
try(
for i=1 to selection.count do bywn[i]=selection[i].name
cywn=cywn-1
)catch cywn=cywn+1
)
fn hello = print "hello"
rollout test "test"
(
button Anims btnname
on Anims pressed do
(
print cywn
)
on test open do
(
callbacks.addScript #selectionSetChanged "hello() xianshi()" id:#Rollout
)
on test close do
(
callbacks.removeScripts #selectionSetChanged id:#Rollout
)
)
createdialog test
--registerRedrawViewsCallback xianshi
+79
View File
@@ -0,0 +1,79 @@
--//图层名称必须唯一
--a=$Sphere001
--b=$Sphere002
--layer0=LayerManager.getLayer 0--//获取图层
--LayerManager.newLayer() --//新建图层
--LayerManager.count --//总图层数量
--layer1=LayerManager.getLayer 1 --//获取图层
--layer1.addnodes #(a,b) --//添加节点到图层
--layer0.addnodes b --//添加节点到图层
--layer1.setname "我是图层1"
--//设置图层名称,返回值如果是false则说明重名
--//返回值是undefined则说明有重名图层
--layer1.addnodes $
--layer1.select on --//选择图层中所有节点,不会选择本图层或者子图层中的节点
--layer1.select off --//取消选择图层中所有
--layer2= layermanager.newLayerFromName "我是图层2" --//使用名称新建图层
--layer1.nodes &abc --//返回层上所有节点到abc数组中,&符号必须有
--print abc
--layerparent=layer3.getparent() --//获取layer3图层的父层,如果没有,返回undefined
--layerparent.name
--layer2.setparent layer0--//设置layer2的父层为layer0
--templayer=layer1.getChild 3 --//返回图层1下的第3个图层,如果没有则返回undefined
--templayer.name
--layer1.getNumChildren() --//返回子图层的数量
--layer3=LayerManager.getLayerFromName "层0121201" --//以名称选择图层,没有则返回undefined
--layer3.candelete() --//该操作不会删除图层,但如果可以删除图层,则返回True,如果由于某些其他原因而无法删除图层,则返回 False。
--layer3=LayerManager.deleteLayerByName "层001" --//以名称删除图层
--layer3=LayerManager.getLayerFromName "我是图层1"
--num=layer3.getNumNodes()--//返回图层中所有节点数量,不包括子图层中的节点数
--layer3.on=false --//获取/设置图层的隐藏显示
--layer3.on=true
--layer3.lock=true --//获取/设置图层的冻结解冻
--layer3.lock=false
--layer0=LayerManager.getLayer 0
--layer0.name
--layer3.current=true--//获取/设置图层是否为当前图层,但只能设置为true,如果设置为false,为非法操作
+25
View File
@@ -0,0 +1,25 @@
try (destroyDialog imagetest001) catch()
rollout imagetest001 "imagetest001"
(
dotNetControl f1 "Windows.Forms.PictureBox" align:#left height:224 width:400 pos:[0,0]
timer clock "testClock" interval:33
label text001 "123"
on clock tick do
(
lab="D:\%´´ÊÀÏîÄ¿¶¯×÷¿â\3dsmax\¹ÖÎï002\creature_arieki_kalastride_fidget_v01"+"\\"+((clock.ticks) as string)+".jpg"
text001.text = lab
imagetest001.f1.ImageLocation=lab
)
on imagetest001 open do clock.active=false
on f1 MouseEnter do (clock.ticks=0;clock.active=true)
on f1 MouseLeave do (clock.ticks=0;clock.active=false)
)
createDialog imagetest001 400 244
+16
View File
@@ -0,0 +1,16 @@
使用说明:https://help.autodesk.com/view/MAXDEV/2022/ENU/?guid=GUID-A6A60FC7-6206-4FFC-80E2-0EF8544BE2C4
findString "Thanks for all the fish!" "all"
-- returns 12
filterString "MAX Script, is-dead-funky" ", -"
#("MAX","Script","is","dead","funky")
s="1234567890"
s1=replace s 5 3 "inserted string"
-- returns "1234inserted string890"
s ="Balerofon"
ss = substring s 5 3-- returns "rof"
ss = substring s 5 -1-- returns "rofon"
ss = substring s 5 100-- returns "rofon"
@@ -0,0 +1,9 @@
--in coordsys local selection.pos=[10,0,0]
--in coordsys local rotate selection (eulerangles 90 0 0)
--rotate $ (eulerangles 90 0 0)
--in coordsys world selection.pos=[10,0,0]
--in coordsys world rotate selection (eulerangles 0 -90 0)
--in coordsys parent
--in coordsys grid
--in coordsys screen
in coordsys $Teapot001 rotate selection (eulerangles 0 -90 0)
+64
View File
@@ -0,0 +1,64 @@
custAttributes.add $Sphere001 the_weaponData --给名为Sphere001的物体添加自定义属性,可包括按钮和各种UI(名称后加*号表示所有相同开头的物体加属性)
--custAttributes.add $Sphere001.modifiers the_weaponData --给名为Sphere001的物体属性承载器添加自定义属性
the_weaponData = attributes weaponData
(
parameters main rollout:params
(
hitPoints type: #float ui:hits default:10
cost type: #float ui:cost default:100
sound type: #string
)
parameters main2 rollout:params2
(
-- hitPointss type: #float ui:hits default:10
-- costs type: #float ui:cost default:100
)
rollout params "叶文斌属性1"
(
spinner hits "Hit Points" type: #float
spinner cost "Cost" type: #float
dropdownlist sound_dd "Sound" items:# ("boom","sparkle","zap","fizzle")
button havepressed "哈哈哈" width:100 height:50
on havepressed pressed do
(
print "cost.name="
print cost.name
print "cost="
print cost.value
print "sound="
print sound
)
)
rollout params2 "叶文斌属性飞过"
(
group "选项" (
radiobuttons uiRBtnLoadingType "第一" labels:#("Name", "Handle") default:1
checkbox uiCBoxAutoHide "第二" across:2
checkbox uiCBoxNonBipedMode "第三"
)
)
)
/*属性访问方法:
直接访问:
$box01.hitPoints
$box01.cost
$box01.sound
方法二:通过属性块访问
$box01.weaponData.hitPoints
$box01.weaponData.cost
$box01.weaponData.sound
*/
+56
View File
@@ -0,0 +1,56 @@
--//常识性
--$foo --在整个场景中查找名为foo的对象,如果有多个同名对象,将只会返回找到的第一个对象
--$/foo --将仅查找名为foo的顶级对象
--$/foo/foo1 --将仅查找foo子级下名为foo1的对象
/*--//在foo下创建一个box
in $foo
(
box()
)
*/
--select $foo* --//旋转所有以foo名称开头的物体
--DisableSceneRedraw() --禁用场景绘制
--EnableSceneRedraw() --启用场景绘制
/*--//撤销块内的操作可以被撤销
undo on
(
delete $box002
delete $foo1
)
max undo --对刚刚的操作进行撤销
clearUndoBuffer() --清理撤销后无法再撤销操作
*/
/*--//撤销块拥有标签 可以指定撤销哪一部分
undo "chexiao" on
(
delete $foo1
)
max undo "chexiao" --撤销名为“chexiao”的撤销块
*/
/*--//with的用法是默认进入某种状态,完成操作后回到操作之前状态
--//with后面常跟animate,undoredraw等操作
a=$foo1
with redraw off --//括号内的内容会在重绘关闭的时候操作,操作完后重绘重新打开
(
at time 0 a.length=100
at time 10 a.length=200
)
*/
/*--//可将多个上下文前缀放在一行里面使用
animate on, at time 0, with undo, in coordsys local
(
)
*/
+51
View File
@@ -0,0 +1,51 @@
/*
-------//控制器只能用控制器赋值,控制器下的子动画可用索引进行访问,但不可赋值
$box001.position.controller==position_list ()--//Position_XYZ ()
$box001.position.controller[1]
$box001.position.controller[2]
$box001.position.controller[3]
$box001.position.controller.x_position=0 --//控制器的属性允许赋值
$box001.pos.x
*/
--$box001.rotation.controller=Euler_XYZ ()
--$box001.rotation.controller[1] --//访问的是控制器指针,指向控制器下的第一个子动画
--$box001.rotation.controller.X_Rotation.controller = tcb_float () --//访问的是控制器,并修改控制器
--$box001.rotation.controller.X_Rotation --//访问的是数值
--$box001.rotation.controller.'X 轴旋转' --//中英文版本相同,但是参数连接器中不同
--$box001.rotation.controller[2]
--$box001.rotation.controller[3]
--//以下可用于控制器列表
--$box001.rotation.controller=rotation_list ()--//tcb_rotation ()--//Euler_XYZ ()
--//尽量仅执行一次,多次执行会多次添加列表控制器
--$box001.rotation.controller.list
--$box001.rotation.controller.available.controller=tcb_rotation () --在列表中新添加控制器
--$box001.rotation.controller.getcount() --获取控制器列表中的控制器数量
--$box001.rotation.controller.setactive 2 --设置激活控制器列表中第2个控制器
--$box001.rotation.controller.getactive()--获取控制器列表中第几个控制器是激活的
--$box001.rotation.controller.delete 2 --删除第2个控制器
--$box001.rotation.controller.getname 2 --获取第2个控制器名称
--$box001.rotation.controller.setname 2 "ywb" --设置第2个控制器名称,仅设置名称而已
--$box001.rotation.controller.ywb.lookat_vector_length=201 --设置控制器某个属性的值
--$box001.rotation.controller.setname 5 "xuanzhuanliebiao"
--$box001.rotation.controller.x_rotation --//四元数/矩阵表示旋转
--$box001.rotation.x
/*
$box001.scale.controller=ScaleXYZ()--//bezier_scale ()
$box001.scale.controller[1]
$box001.scale.controller[2]
$box001.scale.controller[3]
*/
+64
View File
@@ -0,0 +1,64 @@
--必须安装有excel才能进行操作,否则报错
-- 创建Excel应用程序对象
excelApp = createOLEObject "Excel.Application"
-- 显示Excel应用程序
excelApp.Visible = false
-- 创建一个新的工作簿
--workbook = excelApp.Workbooks.Add()
workbook=excelApp.Workbooks.open(excelFile)
-- 获取活动工作表
sheet = workbook.ActiveSheet
-- 写入数据到单元格A1
(sheet.Cells 1 1).Value = "Hello"
(sheet.Cells 1 2).Value = "World!"
-- 保存工作簿到指定路径
--workbook.SaveAs "D:\\Desktop\\123.xlsx"
workbook.Save()
-- 关闭工作簿
workbook.Close()
-- 退出Excel应用程序
excelApp.Quit()
/*-- Startup Ops
-- Generate a filename
--这里是excel文件的绝对路径
excelFile = "D:\\Desktop\\123.xlsx"
-- Start an Excel OLE Object
x = CreateOLEObject "Excel.Application"
-- Create a new workbook in the new excel document
x.application.Workbooks.open(excelFile)
-- This makes Excel Visible
-- true的话脚本运行时看到打开excel
x.visible = false
--示例 获取表中11位置的数据
pictureNum = (x.ActiveSheet.Cells 1 1).Value
(x.ActiveSheet.Cells 1 1).Value="12345"
--之后是释放操作,如果未执行会导致excel文件一直被占用,只能以只读被打开
-- Cleanup Ops
-- Close the spreadsheet
x.application.ActiveWorkbook.Close
-- quit excel
x.quit()
-- Release the OLE Object
releaseOLEObject x
-- Release ALL OLE Objects, just in case
releaseAllOLEObjects()
*/
+10
View File
@@ -0,0 +1,10 @@
a=#("a","b","c","d","e")
b=#("x","y","z")
c="s"
append a "f"
appendIfUnique a "f" --对比如果有 则附加
deleteitem a a.count --删除a索引位置的元素
join a b --只能是数组 不能join a c
insertItem c a 3 --把c插入a的第3个位置
findItem a "k" --寻找不成功返回0 成功返回索引
a
+19
View File
@@ -0,0 +1,19 @@
f=fopen "C:\Users\ab\Desktop\a.bin" "wb"
WriteString f "String"
WriteByte f 64
WriteShort f 128
WriteLong f 256
WriteFloat f 512.0
WriteString f "gnirtS"
WriteLong f (ftell f)
fclose f
f=fopen "C:\Users\ab\Desktop\a.bin" "rb"
ReadString f
ReadByte f
ReadShort f
ReadLong f
ReadFloat f
ReadString f
ftell f
ReadLong f
fclose f
+6
View File
@@ -0,0 +1,6 @@
--filename = getOpenFileName()
--filepath=getSavePath caption:"mt" initialdir:"D:\Users\ab\Desktop\1"
arr=getfiles "D:\Bip动作库\bip\走路\*"
dir=getDirectories "D:\Bip动作库\bip\*"
print dir
print arr
+49
View File
@@ -0,0 +1,49 @@
/*
a=createfile "C:\Users\ab\Desktop\\test.txt"
b=10
print 5 to:a
format "%,%\n" 1 2 to:a
print b to:a
format "%,%\n" 3 4 to:a
close a
free a
*/
openf=openfile "C:\Users\ab\Desktop\\test.txt"
if openf !=undefined then
(
i=readValue openf
j=readline openf
k=readValue openf
format "filepos=%\n" (filepos openf)
seek openf 0
l=readValue openf
m=readValue openf
format "i=%\n" i
format "j=%\n" j
format "k=%\n" k
format "l=%\n" l
format "m=%\n" m
format "\n\n"
print j
eof openf
flush openf
)
free openf
close openf
+30
View File
@@ -0,0 +1,30 @@
--//坐标解释
--//在表达式、操作或块表达式前面加上上下文前缀会导致在指定的坐标系中解释3D坐标操作
--//注:用法类似于animate on 仅影响块、后续表达式或下一行表达式
/*
in coordsys world --//使用世界坐标系
in coordsys local --//使用局部坐标系
in coordsys parent --//使用父级坐标系
in coordsys grid --//使用活动网格坐标系
in coordsys screen --//使用屏幕坐标系
in coordsys <node> --//使用节点对象坐标系
in coordsys <Matrix3> --//使用3D矩阵坐标系
*/
--//欧拉旋转
--a=$Box002
--rot=EulerAngles 0 10 0 --//定义一个特殊的欧拉对象rot
--rotate a rot --//将欧拉对象应用于对象a
--rotate a (EulerAngles 0 10 0) --//与上式等效
--rotate a 10 y_axis --//与上式等效
--//例如:
--in coordsys local selection.pos=random[-20,0,0][20,0,0] --//局部x轴随机位移-20到20的距离
--in coordsys local rotate selection (EulerAngles 0 10 0) --//局部坐标轴下绕y轴旋转10度
--in coordsys world rotate selection (EulerAngles 10 0 0) --//世界坐标轴下绕y轴旋转10度
--in coordsys world rotate selection 10 y_axis --//世界坐标轴下绕y轴旋转10度
+17
View File
@@ -0,0 +1,17 @@
function local_sys_time= -----获取时间的函数,返回值是字符串
(
local local_time=timeStamp()
local shijian=(((local_time/1000.0)/60.0)/60.0)
local xiaoshi=shijian as integer
local fenzhong=((shijian-xiaoshi)*60) as integer
local kkk=(local_time/1000.0)-xiaoshi*60.0*60.0-fenzhong*60.0
local miao=((local_time/1000.0)-xiaoshi*60.0*60.0-fenzhong*60.0 )as integer
local haomiao=((kkk-miao)*100) as integer
local h=xiaoshi as string
local m=fenzhong as string
local s=miao as string
local f=haomiao as string
return ("当前时间为:"+h+"小时"+m+"分钟"+s+"秒"+f)
)
a=local_sys_time()
+77
View File
@@ -0,0 +1,77 @@
/*fn shape001=
(
ss=SplineShape()
addNewSpline ss
addKnot ss 1 #corner #curve [0,0,0]
addKnot ss 1 #corner #curve [100,0,0]
addNewSpline ss
addKnot ss 2 #corner #curve [0,10,0]
addKnot ss 2 #corner #curve [100,10,0]
addNewSpline ss
addKnot ss 3 #corner #curve [0,20,0]
addKnot ss 3 #corner #curve [100,20,0]
updateShape ss
addKnot ss 2 #corner #curve [200,10,0]
updateShape ss
ss.pos=[0,0,100]
a=Rectangle()
convertToSplineShape a
b=Circle()
convertToSplineShape b
addAndWeld a ss 0
addAndWeld a b 0
updateShape a
return a
)
b=shape001()
print "***************"
print b*/
/*for shapes in selection do
(
if not isShapeObject shapes do continue
print "123"
)*/
--isShapeObject shapes--判断曲线
--numSplines shapes --曲线对象包含几根
--numKnots shapes i --第i条曲线节点数量
--getKnotPoint shapes i j--第i条曲线第j个顶点位置
--$.transform
--inverse $.transform
/*getPointController $ 1 2*/
--if keyboard.escPressed then exit
--setKnotPoint shapes i j transvertTM.position
/*setKnotPoint $ 1 1 [100,0,0]
setKnotPoint $ 1 2 [200,0,0]
setKnotPoint $ 1 3 [300,0,0]
updateShape $*/
--DisableSceneRedraw()--关闭视口场景绘制
--completeRedraw()--视口刷新
--ForceCompleteRedraw()--所有视口强制刷新
--redrawViews()--仅刷新已经更改的部分
--makedir "C:\\Users\\ab\\Desktop\\yewenbin\\" --建立文件夹
--setINISetting "$scripts\\DTools\jiaoben_weizhi.ini" "splineAnime" "splineAnime_weizhi" (splineAnime_weizhi as string )
+80
View File
@@ -0,0 +1,80 @@
(
-- 这是一个关于如何使用MySQL Connector查询MySQL数据库的小教程。
-- 本教程假设您已经设置了MySQL服务器,安装了MySQL Connector(可在MySQL官网找到),并且具有SQL的基本知识。
-- 我将在不久的将来创建一个更易于使用的封装。
-- 祝您愉快。
-- Ofer Zelichoverwww.oferz.com2008-03-08
--ySQL Connector下载链接:https://www.mysql.com/products/connector 下载时选择.net版本就行,一路默认安装即可
-- 首先加载dotNet程序集。确保字符串指向安装了MySQL Connector DLL文件的位置。
dotNet.loadAssembly "C:\\Program Files (x86)\\MySQL\\MySQL Connector NET 8.2.0\\MySql.Data.dll"
-- 现在定义连接参数。
local host = "localhost" -- MySQL服务器的名称
local database = "test" -- 要使用的数据库的名称
local user = "test" -- 要使用的用户名
local password = "test" -- 要使用的密码
-- 构建连接字符串
local connectionString = "Database=" + database + ";Data Source=" + host + ";User Id=" + user + ";Password=" + password
-- 创建连接对象
local DBConnection = dotNetObject "MySql.Data.MySqlClient.MySqlConnection"
-- 使用连接字符串设置连接参数。
DBConnection.ConnectionString = connectionString
-- 打开数据库连接
DBConnection.open()
-- 打印连接状态:1 - 已连接;0 - 未连接。
print DBConnection.state.value__
-- 添加两行新记录
local cmdObject = DBConnection.CreateCommand()
cmdObject.commandText = "INSERT INTO test_table (`name`, `phone`) VALUES ('另一个名字','1234567890'), ('又一个名字','2468101214')"
local readerObject = cmdObject.ExecuteReader()
-- 打印受影响的行数
format "添加了 % 行\n" readerObject.RecordsAffected
readerObject.close()
-- 更改表中第二行的值:
local cmdObject = DBConnection.CreateCommand()
cmdObject.commandText = "UPDATE test_table tt SET tt.name='修改后的名字', tt.phone=78978979 WHERE tt.id=2"
local readerObject = cmdObject.ExecuteReader()
-- 打印受影响的行数
format "修改了 % 行\n" readerObject.RecordsAffected
readerObject.close()
-- 查询数据库:
-- 首先创建一个命令对象。该对象用于将查询发送到数据库。
local cmdObject = DBConnection.CreateCommand()
-- 定义要执行的SQL查询:
cmdObject.commandText = "SELECT * FROM test_table tt"
-- 然后执行命令以创建读取器对象。
local readerObject = cmdObject.ExecuteReader()
-- 打印结果中的字段名:
for i = 0 to (readerObject.FieldCount - 1) do
print (readerObject.getName i)
-- 打印结果:
-- readerObject.read()方法将读取器对象中的记录移至下一条记录。
while readerObject.read() do (
local record = readerObject.item
-- 现在打印记录的值。这假设您知道字段名:
format "%\t%\t%\n" record["id"] record["name"] record["phone"]
-- 如果不想使用显式字段名,还有另一种选择:
for i = 0 to (readerObject.FieldCount - 1) do
format "%\t" record[i]
format "\n"
)
-- 关闭读取器对象
readerObject.close()
-- 关闭连接
DBConnection.close()
)
@@ -0,0 +1,30 @@
dotNet.loadAssembly "C:\\Program Files (x86)\\MySQL\\MySQL Connector NET 8.2.0\\MySql.Data.dll"
host = "81.71.134.168" -- The name of the MySQL server
database = "admin" -- The name of the database to use
user = "admin123" -- The user name to use
password = "aiAtB23yajDj2Lpa" -- The password to use
connectionString = "Database=" + database + ";Data Source=" + host + ";User Id=" + user + ";Password=" + password
DBConnection = dotNetObject "MySql.Data.MySqlClient.MySqlConnection"
DBConnection.ConnectionString = connectionString
DBConnection.open()
-- Print the connection status: 1 - connected; 0 - not connected.
print DBConnection.state.value__
-- Add a new rows
cmdObject = DBConnection.CreateCommand()
cmdObject.commandText ="INSERT INTO `admin`.`students`(`id`, `name`, `age`, `score`, `birthday`, `insert_time`) VALUES (132, 'name03', 16, 35, '2023-11-23', '2023-12-13 10:50:56')"
readerObject = cmdObject.ExecuteReader()
-- 打印受影响的行数
format "添加了 % 行\n" readerObject.RecordsAffected
readerObject.close()
-- 查询数据库:
-- 首先创建一个命令对象。该对象用于将查询发送到数据库。
cmdObject = DBConnection.CreateCommand()
-- 定义要执行的SQL查询:
cmdObject.commandText = "SELECT * FROM `admin`.`students`"
-- 然后执行命令以创建读取器对象。
readerObject = cmdObject.ExecuteReader()
+30
View File
@@ -0,0 +1,30 @@
try(destroyDialog YeomaiDataBaseConnectionTest)catch()
try(dotNet.loadAssembly "C:\\Program Files (x86)\\MySQL\\MySQL Connector NET 8.2.0\\MySql.Data.dll")catch(messagebox("dll载入失败,插件无法使用"))
rollout YeomaiDataBaseConnectionTest "无标题" width:837 height:639
(
label 'lbl1' "服务器" pos:[100,100] width:53 height:13 align:#right
label 'lbl2' "数据库名" pos:[100,130] width:53 height:13 align:#right
label 'lbl3' "用户名" pos:[100,160] width:23 height:13 align:#right
label 'lbl4' "密码" pos:[100,190] width:23 height:13 align:#right
editText 'host' "" pos:[170,100] width:241 height:22 align:#left text:"81.71.134.168"
editText 'database' "" pos:[170,130] width:241 height:22 align:#left text:"admin"
editText 'user' "" pos:[170,160] width:241 height:22 align:#left text:"admin123"
editText 'password' "" pos:[170,190] width:241 height:22 align:#left text:"aiAtB23yajDj2Lpa"
button 'btn1' "连接数据库" pos:[170,240] width:84 height:23 align:#left
button 'btn2' "断开数据库" pos:[280,240] width:84 height:23 align:#left
on 'btn1' pressed do(
connectionString = "Database=" + database.text + ";Data Source=" + host.text + ";User Id=" + user.text + ";Password=" + password.text
DBConnection = dotNetObject "MySql.Data.MySqlClient.MySqlConnection"
DBConnection.ConnectionString = connectionString
DBConnection.open()
if DBConnection.state.value__ then messagebox("连接成功!") else messagebox("连接失败!")
)
on 'btn2' pressed do(
-- 关闭连接
if DBConnection.state.value__ then (DBConnection.close();messagebox("断开连接!"))
)
)
createDialog YeomaiDataBaseConnectionTest
+16
View File
@@ -0,0 +1,16 @@
addModifier $ (Spline_IK_Control())
$.Spline_IK_Control.box=false
$.Spline_IK_Control.helper_cross = false
$.Spline_IK_Control.linktypes=2
$.Spline_IK_Control.gethelpercount()
$.Spline_IK_Control.getknotcount()
$.Spline_IK_Control.createhelper 2
a=$.Spline_IK_Control.helper_list[1]
a.pos=[100,0,0]
b=$.Spline_IK_Control.helper_list[2]
b.pos=[200,0,0]
+29
View File
@@ -0,0 +1,29 @@
set animate off
a=$Box002
b=$Box003
c=$Box004
--//位置约束
--a.pos.controller=Position_Constraint()
--a.pos.controller.appendTarget b 100 --添加Sphere005为约束目标 权重值为100
--a.pos.controller.relative=on --保持初始偏移
--a.pos.controller.getweight 4 --获取第四个约束的权重值
--a.pos.controller.setweight 3 60 --设置第三个约束的权重为60
--nodename=(a.pos.controller.getnode 1) --获取第1个约束的节点
--print nodename.name
--show a.pos.controller
--//旋转约束
a.rotation.controller=Orientation_Constraint()
a.rotation.controller.appendTarget b 100
a.rotation.controller.relative=on
a.rotation.controller.getweight 2
a.rotation.controller.setweight 1 60
nodename=(a.rotation.controller.getnode 1)
print nodename.name
show a.pos.controller
+99
View File
@@ -0,0 +1,99 @@
--macroScript MicroPaint category: "HowTo"
(
global MicroPaint_CanvasRollout
try (destroyDialog MicroPaint_CanvasRollout) catch()
local isDrawing = false
local bitmapX = bitmapY = 512
global theCanvasBitmap = bitmap bitmapX bitmapY color:white
local currentPos = lastPos = [0,0]
rollout MicroPaint_CanvasRollout "MicroPaint"
(
bitmap theCanvas pos:[0,0] width:bitmapX height:bitmapY bitmap:theCanvasBitmap
colorpicker inkColor height:16 modal:false color:black across:4
checkbutton airBrush "AirBrush"width:50
spinner AirBrushSpeed "Speed" range:[0.1,50,10] fieldwidth:30
spinner BrushSize "Size" range:[1,50,10] type:#integer fieldwidth:40
listbox BrushShape items:#("Circle","Box","Circle Smooth") pos:[bitmapX+5,0] width:90
dotNetControl f1 "Windows.Forms.PictureBox" align:#left height:bitmapY width:bitmapX pos:[bitmapX+100,0]
fn paintBrush pos =
(
case BrushShape.selection of
(
1: (
if distance pos currentPos <= BrushSize.value/2 do
setPixels theCanvasBitmap pos #(inkColor.color)
)
2: setPixels theCanvasBitmap pos #(inkColor.color)
3: (
theFactor = (distance pos currentPos) / (BrushSize.value/2.0)
if theFactor <= 1.0 do
(
theFactor = sin ( 90.0 * theFactor)
thePixels = getPixels theCanvasBitmap pos 1
if thePixels[1] != undefined do
(
thePixels[1] = (thePixels[1] * theFactor) + (inkColor.color * (1.0 - theFactor))
setPixels theCanvasBitmap pos thePixels
)
)
)--end case 3
)--end case
)--end fn
fn drawStroke lastPos pos =
(
currentPos = lastPos
deltaX = pos.x - lastPos.x
deltaY = pos.y - lastPos.y
maxSteps = amax #(abs(deltaX),abs(deltaY))
deltaStepX = deltaX / maxSteps
deltaStepY = deltaY / maxSteps
for i = 0 to maxSteps do
(
if airBrush.checked then
(
for b = 1 to (BrushSize.value / AirBrushSpeed.value) do
paintBrush (currentPos + (random [-BrushSize.value/2,-BrushSize.value/2] [BrushSize.value/2,BrushSize.value/2] ))
)
else
for b = -BrushSize.value/2 to BrushSize.value/2 do
for c = -BrushSize.value/2 to BrushSize.value/2 do
paintBrush (currentPos + [c,b])
currentPos += [deltaStepX, deltaStepY]
)
theCanvas.bitmap = theCanvasBitmap
/*
local grab_bmp1
grab_bmp1 = bitmap 512 512 color:white
copy theCanvasBitmap grab_bmp1
grab_bmp1.filename ="D:\\Desktop\\123.png"
save grab_bmp1
f1.ImageLocation="D:\\Desktop\\123.png"
*/
)
on MicroPaint_CanvasRollout lbuttondown pos do
(
lastPos = pos
isDrawing = true
drawStroke lastPos pos
)
on MicroPaint_CanvasRollout lbuttonup pos do isDrawing = false
on MicroPaint_CanvasRollout mousemove pos do
(
if isDrawing do drawStroke lastPos pos
lastPos = pos
)
)
createDialog MicroPaint_CanvasRollout (bitmapx+620) (bitmapy+30)
)
/*
clearlistener(); showProperties MicroPaint_CanvasRollout.f1
MicroPaint_CanvasRollout.f1.ImageLocation="D:\\Desktop\\123.png"
show MicroPaint_CanvasRollout.theCanvas.bitmap
-- MicroPaint_CanvasRollout.f1.image= (dotnetclass "System.Drawing.Graphics").FromImage
*/
+4
View File
@@ -0,0 +1,4 @@
--脚本加密方法:
--例如encryptScript "C:\Users\ab\Desktop\DTrajEdit.ms" version:1
--version为0 使用max2-max9的旧加密方法 为1 使用max9 sp1中引入的新方案
--新方案无法在旧版max中运行
+3
View File
@@ -0,0 +1,3 @@
currentFolder001 = getFilenamePath (getThisScriptFilename())
rulesScript = pathConfig.appendPath currentFolder001 "\SpineBones.ms"
+64
View File
@@ -0,0 +1,64 @@
--菜单文件路径-保存--读取
--menuMan.getMenuFile()
--menuMan.saveMenuFile (menuMan.getMenuFile())
--注销已存在的菜单
try(menuMan.unRegisterMenu (menuMan.findMenu "叶文斌"))catch()
try(menuMan.unRegisterMenu (menuMan.findMenu "叶文斌(二级菜单)"))catch()
--宏脚本定义,会在#usermacroscript目录下生成宏脚本文件
macroScript Free_Camera category:"Yewenbin" tooltip:"Free Camera"
(
StartObjectCreation FreeCamera
)
macroScript Target_Camera category:"Yewenbin"
(
StartObjectCreation TargetCamera
)
macroScript 文件 category:"Yewenbin"
(
print "文件宏脚本"
)
--生成目录和子目录
menusmtool = menuman.createmenu "叶文斌"
menusmtool02 = menuman.createmenu "叶文斌(二级菜单)"
submainmenuitem = menuman.createsubmenuitem "A01第一个" menusmtool
submainmenuitem01 = menuman.createsubmenuitem "A02第二个" menusmtool02
SeparatorItem001=menuMan.createSeparatorItem()
macroScript001=menuMan.createActionItem "文件" "Yewenbin"
macroScript002=menuMan.createActionItem "Free_Camera" "Yewenbin"
macroScript003=menuMan.createActionItem "Target_Camera" "Yewenbin"
SeparatorItem001=menuMan.createSeparatorItem()
menusmtool.addItem macroScript001 1
menusmtool.addItem macroScript002 2
menusmtool.addItem SeparatorItem001 3
menusmtool.addItem macroScript003 4
menusmtool.addItem SeparatorItem001 5
menusmtool.addItem submainmenuitem01 6
menusmtool02.addItem macroScript001 1
menusmtool02.addItem macroScript002 2
menusmtool02.addItem SeparatorItem001 3
menusmtool02.addItem macroScript003 4
menusmtool02.addItem SeparatorItem001 5
mainmenubar = menuman.getmainmenubar()
mainmenubar.addItem submainmenuitem (mainmenubar.numItems()+1)
menuman.updatemenubar()
/*
findme=menuMan.findMenu "AAAyewenbin"
menuMan.unRegisterMenu findme
*/
+12
View File
@@ -0,0 +1,12 @@
x_old=gw.getWinSizeX()
y_old=gw.getWinSizeY()
gw.setPos 0 0 200 112 --设置视口从[0,0]开始,到[400,200]结束的大小
x= gw.getWinSizeX() --获取视口横向大小
y= gw.getWinSizeY() --获取视口竖向大小
grab_tempbmp1 = gw.getViewportDib() --生成视口缩略图(系统存放在一个临时变量中,api的返回值是一个临时变量,需要把它赋值出来)
gw.setPos 0 0 x_old y_old
grab_bmp1 = bitmap x y color:[0,0,0]
copy grab_tempbmp1 grab_bmp1
grab_bmp1.filename = "C:\Users\ab\Desktop\CopyPaste222.bmp"
save grab_bmp1
+3
View File
@@ -0,0 +1,3 @@
--连续命名选择的物体为objects 以第一个可用的名称+序号开始
for i in selection do (i.name = uniqueName "objects")
+27
View File
@@ -0,0 +1,27 @@
/*
小脚本说明:获取顶点位置的方法
yeomai_test=$shixinvpu_new
yeomai_helper=$Point001
disableSceneRedraw()
set animate on
for i=1 to polyop.getNumVerts yeomai_test do
(
at time i
yeomai_helper.pos=polyop.getVert yeomai_test i
)
set animate off
enableSceneRedraw()
小脚本说明:获取控制器关键帧的方法
getKeyTime $.rotation.controller 1
getKeyTime $.rotation.controller (numKeys $.rotation.controller)
*/
@@ -0,0 +1,64 @@
This software makes use of the following components:
AudioToolsLibrary
~~~~~~~~~~~~~~~~~
Copyright (c) 2000-2002 by Jurgen Faul
Copyright (c) 2003-2005 by The MAC Team
Web: http://mac.sourceforge.net/atl/
Email: macteam@users.sourceforge.net
dEXIF
~~~~~
Copyright © 2001 - 2006 Gerry McGuire
Web: http://mcguirez.homestead.com/
PascalScript
~~~~~~~~~~~~
Copyright © RemObjects Software
Web: http://www.remobjects.com/ps
RegExpr
~~~~~~~
Copyright (c) 1999-2004 Andrey V. Sorokin, St.Petersburg, Russia
Email: anso@mail.ru
Web: http://RegExpStudio.com
Web: http://anso.da.ru/
SimpleIPC
~~~~~~~~~
Copyright (c) 2002-2003 Sunisoft
Web: http://www.sunisoft.com
Email: support@sunisoft.com
SMComponents
~~~~~~~~~~~~
Copyright (c) 1998-2005, written by Mike Shkolnik, Scalabium Software
Email: mshkolnik@scalabium
Email: mshkolnik@yahoo.com
Web: http://www.scalabium.com
Virtual Treeview
~~~~~~~~~~~~~~~~
The initial developer of the original code is digital
publishing AG (www.digitalpublishing.de).
Virtual Treeview is written, published and maintaned by
Mike Lischke (public@soft-gems.net, www.soft-gems.net).
(c) 1999-2005 Mike Lischke, Soft Gems software solutions.
DCPCrypt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DCPcrypt is copyrighted (c) 1999-2003 David Barton.
All trademarks are property of their respective owners.
Farm-Fresh Web Icons
~~~~~~~~~~~~~~~~~~~~
Some icons were taken from Farm-Fresh Web Icons collection.
http://www.fatcow.com/free-icons
famfamfam Flag Icons
~~~~~~~~~~~~~~~~~~~~
These icons are public domain, and as such are free for any use
(attribution appreciated but not required).
Contact: mjames@gmail.com
http://www.famfamfam.com
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Some files were not shown because too many files have changed in this diff Show More