Windows 11
I am not a scripter, i know very basic Scripting in Lua and have experience in hmtl, css ,and some c++ and C# basics. So Im not at all a programmer, but i have gotten this far so far with the help of the amazing Mohoscripting.com ( Huge Shoutout!!!) and GPT4o, and Shout out to the AE_Recolor Script on mohoscrips.com for being a greet example of what i want to achieve but instead of a UI i want to achieve it with JSON.
My Goal:
# DEFINING OUR SCRIPTS GOALS
1. **Gather All Layer Names**:
- Recursively scan through all layers and sublayers in the Moho document.
- Maintain a list of all layer names found during the scan.
2. **Disregard Any Layers Not Mentioned in the JSON**:
- Compare the gathered layer names with those specified in the JSON.
- Filter out any layers that do not match the names provided in the JSON.
3. **Parse Through Shapes Only in Identified Layers**:
- For each identified layer, iterate through its shapes to access their color properties.
4. **Identify Each Shape's Current Color**:
- For each shape in the identified layers, retrieve its current fill and line colors.
- If the current colors of the shape are not mentioned in the JSON, skip further processing for that shape.
5. **Change Colors as Specified in the JSON**:
- If the current colors of the shape match those specified in the JSON, update the shape's fill and line colors to the new values provided.
- Ensure that both fill and line colors are handled separately, as specified by the JSON.
6. **Apply and Refresh the Document**:
- Once all shapes have been processed, apply the changes to the document.
- Refresh or redraw the document to ensure that all changes are visible and committed.
The Attached a MVP i have developed so far in an attempt to meet the above goals. The script and json only works so far in Moho for my character models to change the colors to white, regardless of the colors iIm trying to map form the JSON..
ChangeColorViaJSON.lua
Code: Select all
-- **************************************************
-- Provide Moho with the name of this script object
-- **************************************************
ScriptName = "ChangeColorViaJSON"
ChangeColorViaJSON = {}
-- **************************************************
-- General information about this script
-- **************************************************
function ChangeColorViaJSON:Name()
return "Change Colors Based on JSON"
end
function ChangeColorViaJSON:Version()
return "1.0"
end
function ChangeColorViaJSON:UILabel()
return "Change Colors Based on JSON"
end
function ChangeColorViaJSON:Creator()
return "JeffSaamanen"
end
function ChangeColorViaJSON:Description()
return "Change shape colors based on a provided JSON file"
end
-- Helper function to read JSON file
function ChangeColorViaJSON:ReadJSONFile(filePath)
local file = io.open(filePath, "r")
if not file then
print("Error: Could not open file " .. filePath)
return nil
end
local json_data = file:read("*all")
file:close()
return json_data
end
-- Function to get the script directory
function getScriptDirectory()
local str = debug.getinfo(2, "S").source:sub(2)
return str:match("(.*[\\])")
end
-- Helper function to parse JSON
function ChangeColorViaJSON:ParseJSON(jsonString)
local scriptDir = getScriptDirectory()
if not scriptDir then
print("Error: Could not get script directory")
return nil
end
local json = dofile(scriptDir .. "/dkjson.lua")
local jsonObj, pos, err = json.decode(jsonString, 1, nil)
if err then
print("Error:", err)
return nil
end
return jsonObj
end
-- Helper function to get JSON file path from user
function ChangeColorViaJSON:GetJSONFilePath()
local filePath = LM.GUI.OpenFile("Select JSON File")
if filePath == "" then
print("File dialog canceled")
return nil
end
return filePath
end
-- Helper function to compare colors
function ChangeColorViaJSON:EqualColors(colorVector, colorTable)
return math.abs(colorVector.r - colorTable.r) < 0.01 and
math.abs(colorVector.g - colorTable.g) < 0.01 and
math.abs(colorVector.b - colorTable.b) < 0.01 and
math.abs(colorVector.a - colorTable.a) < 0.01
end
-- Helper function to convert color structure to color vector
function ChangeColorViaJSON:CreateColorVector(colorTable)
return LM.ColorVector:new_local(colorTable.r, colorTable.g, colorTable.b, colorTable.a)
end
-- Main function to run the script
function ChangeColorViaJSON:Run(moho)
print("Run function called")
if moho == nil then
print("Error: moho is nil")
return
end
-- Get JSON file path from user
local jsonFilePath = self:GetJSONFilePath()
if not jsonFilePath then
return
end
-- Read JSON data from file
local json_data = self:ReadJSONFile(jsonFilePath)
if not json_data then
return
end
-- Parse the JSON data
local colorData = self:ParseJSON(json_data)
if not colorData then
return
end
-- Iterate through all layers to find and process vector layers
for i = 0, moho.document:CountLayers() - 1 do
local layer = moho.document:Layer(i)
self:ProcessLayers(moho, layer, colorData, moho.frame)
end
-- Refresh the document
moho.document:SetDirty()
moho:UpdateSelectedChannels()
moho.layer:UpdateCurFrame()
end
-- Recursive function to process all layers and sublayers
function ChangeColorViaJSON:ProcessLayers(moho, layer, colorData, frame)
if layer:IsGroupType() then
local group = moho:LayerAsGroup(layer)
for i = 0, group:CountLayers() - 1 do
self:ProcessLayers(moho, group:Layer(i), colorData, frame)
end
elseif layer:LayerType() == MOHO.LT_VECTOR then
print("Processing vector layer: " .. layer:Name())
self:ProcessShapes(moho, layer, colorData, frame)
end
end
-- Function to process shapes in a vector layer
function ChangeColorViaJSON:ProcessShapes(moho, layer, colorData, frame)
local vectorLayer = moho:LayerAsVector(layer)
local mesh = vectorLayer:Mesh()
for i = 0, mesh:CountShapes() - 1 do
local shape = mesh:Shape(i)
if shape and shape.fMyStyle then
local fillColor = shape.fMyStyle.fFillCol:GetValue(frame)
local lineColor = shape.fMyStyle.fLineCol:GetValue(frame)
for _, colorPair in ipairs(colorData.colors) do
local oldFillColor = colorPair.oldFillColor
local newFillColor = colorPair.newFillColor
local oldLineColor = colorPair.oldLineColor
local newLineColor = colorPair.newLineColor
if self:EqualColors(fillColor, oldFillColor) then
print(string.format("Changing fill color from (%.2f, %.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f, %.2f)",
fillColor.r, fillColor.g, fillColor.b, fillColor.a,
newFillColor.r, newFillColor.g, newFillColor.b, newFillColor.a))
shape.fMyStyle.fFillCol:SetValue(frame, self:CreateColorVector(newFillColor))
end
if self:EqualColors(lineColor, oldLineColor) then
print(string.format("Changing line color from (%.2f, %.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f, %.2f)",
lineColor.r, lineColor.g, lineColor.b, lineColor.a,
newLineColor.r, newLineColor.g, newLineColor.b, newLineColor.a))
shape.fMyStyle.fLineCol:SetValue(frame, self:CreateColorVector(newLineColor))
end
end
else
print("Error: shape or shape.fMyStyle is nil")
end
end
end
return ChangeColorViaJSON
colorchange-v3.json
Code: Select all
{
"colors": [
{
"oldFillColor": {"r": 0.44, "g": 0.19, "b": 0.19, "a": 1.00},
"newFillColor": {"r": 0.00, "g": 0.25, "b": 0.25, "a": 1.00},
"oldLineColor": {"r": 0.32, "g": 0.07, "b": 0.07, "a": 1.00},
"newLineColor": {"r": 0.00, "g": 0.16, "b": 0.16, "a": 1.00}
}
]
}
Everything works except the recoloring. As you can see, there is a major discrepancy between the color defined by the JSON input and the colors the script actually applies to each vector shape.
Code: Select all
{
"colors": [
{
"oldFillColor": {"r": 0.44, "g": 0.19, "b": 0.19, "a": 1.00},
"newFillColor": {"r": 0.00, "g": 0.25, "b": 0.25, "a": 1.00},
"oldLineColor": {"r": 0.32, "g": 0.07, "b": 0.07, "a": 1.00},
"newLineColor": {"r": 0.00, "g": 0.16, "b": 0.16, "a": 1.00}
}
]
}

In the Lua console, it's displaying the correct colors that are supposed to be changed, as if it has successfully changed to the proper color. However, as we can see from the provided image, this is not true; it just changes everything to white.
Please advise as to why this is happening? I feel like i'm just missing something Fundamental about access and passing color information to shapes to change them properly based on the JSON data provided.