Change vector Shapes Fill & Line Color Via JSON

Moho allows users to write new tools and plugins. Discuss scripting ideas and problems here.

Moderators: Víctor Paredes, Belgarath, slowtiger

Post Reply
User avatar
caderial
Posts: 12
Joined: Mon Jul 08, 2024 8:00 pm

Change vector Shapes Fill & Line Color Via JSON

Post by caderial »

Moho Version 14.2
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

and my JSON File:
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}
        }
    ]
}
As you can see n the attached image, The output log is attached as an image, along with an image showing the expected colors and the colors actually assigned by the end of the script.

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}
        }
    ]
}
Image

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.
User avatar
hayasidist
Posts: 3829
Joined: Wed Feb 16, 2011 8:12 pm
Location: Kent, England

Re: Change vector Shapes Fill & Line Color Via JSON

Post by hayasidist »

A very superficial scan of this leads me to think that, as the printout gives the right values but the action of setting does not, there is something wrong with how CreateColorVector(newFillColor) is working.

I'm not wholly convinced that LM.ColorVector:new_local(colorTable.r, colorTable.g, colorTable.b, colorTable.a) will do what you expect. [I haven't run a test to check this.]
EDIT: I have now checked this and you can't combine create and initialise

so the first thing I'd do is break the compact code into smaller steps as below and if that still doesn't work ...
the next thing I'd do is remove the comment-out from the diagnostic prints in the code below to make sure that what it's returning is what you'd expect.

If that doesn't fix it we'll look again.

----
e.g. rather than

return LM.ColorVector:new_local(colorTable.r, colorTable.g, colorTable.b, colorTable.a)

use:

Code: Select all

--	print (string.format("Input (%.2f, %.2f, %.2f, %.2f)", colorTable.r, colorTable.g, colorTable.b, colorTable.a))
	local cv LM.ColorVector:new_local()
	cv:Set(colorTable)
--	print (string.format("Output (%.2f, %.2f, %.2f, %.2f)",  cv.r, cv.g, cv.b, cv.a))
 	return cv
Last edited by hayasidist on Wed Jul 17, 2024 1:22 pm, edited 1 time in total.
User avatar
caderial
Posts: 12
Joined: Mon Jul 08, 2024 8:00 pm

Re: Change vector Shapes Fill & Line Color Via JSON

Post by caderial »

Thanks for the reply, hayasidist!

I actually figured i out last night before bed and it as how i was accessing the RGB Values and setting them, I tweaked the code a lot more since, and working code now runs via another script instead of a direct dialog pop up for the json: This solution can be augmented to directly pass the json to the script for anyone who might need a similar solution

I was hoping for a solution that would let me be able to change the color and fill of specifically identified Styles , but found the styles and their colors inaccessible (Unless anyone knows a trick!?) instead i had to parse through all vector objects to search for Color matches and then swap them based on the JSON.

Here is my current working code for anyone who ight find it helpful:

Code: Select all

-- Define the script name
ScriptName = "ChangeColorViaJSON"

-- Create a table to hold the script functions
ChangeColorViaJSON = {}

-- Function to provide the name of the script
function ChangeColorViaJSON:Name()
    return "Change Colors Based on JSON"
end

-- Function to provide the version of the script
function ChangeColorViaJSON:Version()
    return "1.0"
end

-- Function to provide a description of the script
function ChangeColorViaJSON:Description()
    return "Change shape colors based on a provided JSON file"
end

-- Function to provide the creator of the script
function ChangeColorViaJSON:Creator()
    return "JeffSaamanen"
end

-- Function to provide the UI label of the script
function ChangeColorViaJSON:UILabel()
    return "Change Colors Based on JSON"
end

-- 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

-- Function to convert color structure to rgb_color
function ChangeColorViaJSON:CreateRGBColor(colorTable)
    local color = LM.rgb_color:new_local()
    color.r = colorTable.r * 255
    color.g = colorTable.g * 255
    color.b = colorTable.b * 255
    color.a = colorTable.a * 255
    return color
end

-- Function to convert a table to a string (for printing purposes)
function tableToString(tbl)
    if type(tbl) ~= "table" then return tostring(tbl) end
    local result, done = {}, {}
    for k, v in ipairs(tbl) do
        table.insert(result, tableToString(v))
        done[k] = true
    end
    for k, v in pairs(tbl) do
        if not done[k] then
            table.insert(result, string.format("%s = %s", tostring(k), tableToString(v)))
        end
    end
    return "{" .. table.concat(result, ", ") .. "}"
end

-- Main function to run the script
function ChangeColorViaJSON:Run(moho, customizations)
    print("Run function called")
    if moho == nil then
        print("Error: moho is nil")
        return
    end

    if not customizations then
        print("Error: customizations is nil")
        return
    end

    -- Print the JSON data passed to the script
    print("Customizations JSON: " .. tableToString(customizations))

    -- Extract color data from the passed JSON
    local colorData = customizations["colors"]
    if not colorData then
        print("Error: No color data found in JSON")
        return
    end

    -- Process the first vector layer and its shapes
    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)
    if not vectorLayer then
        print("Error: Layer is not a vector layer")
        return
    end
    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) do
                local oldFillColor = colorPair.oldFillColor
                local newFillColor = self:CreateRGBColor(colorPair.newFillColor)
                local oldLineColor = colorPair.oldLineColor
                local newLineColor = self:CreateRGBColor(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 / 255, newFillColor.g / 255, newFillColor.b / 255, newFillColor.a / 255))
                    shape.fMyStyle.fFillCol:SetValue(frame, 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 / 255, newLineColor.g / 255, newLineColor.b / 255, newLineColor.a / 255))
                    shape.fMyStyle.fLineCol:SetValue(frame, newLineColor)
                end
            end
        else
            print("Error: shape or shape.fMyStyle is nil")
        end
    end
end

return ChangeColorViaJSON
Hope this keeps someone else from banging their head against the LUA/MOHO API wall lol <3
User avatar
hayasidist
Posts: 3829
Joined: Wed Feb 16, 2011 8:12 pm
Location: Kent, England

Re: Change vector Shapes Fill & Line Color Via JSON

Post by hayasidist »

glad you've got it sorted.

Just as a pointer if you're planning on making the finished script public, could you take a look at script structure for naming conventions for your Lua globals. (e.g. add JS_ or any other prefix of your choice to global functions etc) -- helps avoid name clashes.

And, ICYMI: you don't need a recursive scan of groups (but no worries if / as it's working!) -- there's a MohoDoc:LayerByAbsoluteID(id) method that will scan all the layers in a document irrespective of hierarchy which is illustrated here.
User avatar
caderial
Posts: 12
Joined: Mon Jul 08, 2024 8:00 pm

Re: Change vector Shapes Fill & Line Color Via JSON

Post by caderial »

So I have had this older version of the script working for some time now, and its still works. but i realized a major shortcoming for our specific needs. So now i am exploring alternative route to achieving the color change utilizing the styles. However i havent been able to find any information specific to the implementation i am thinking about.

Is it possible to use Moho's Style system to programmatically switch pre-defined styles on layers or shapes based on a JSON file? The goal would be to have a script that parses the JSON to identify specified style changes (e.g., replacing "SkinTone1" with "SkinTone2") and applies these updates across all relevant layers and shapes in the project, without modifying the styles themselves or directly interacting with vector colors, but instead just setting the style applied to the other pre defined style int he scene programmatically.
for example"

Code: Select all

{
    "style_changes": [
        {
            "current_style": "SkinTone1",
            "new_style": "SkinTone2"
        },
        {
            "current_style": "ClothingPrimary1",
            "new_style": "ClothingPrimary2"
        }
    ]
}
Where "SkinTone1","SkinTone2", "ClothingPrimary1", and "ClothingPrimary2" are all pre made styles created in the scene before the script it used, and the lua script uses that JSON to identify or find the layers or items that have the First style applied, and simply change it to the second style defined defined by the JSON? I know styles used to be finicky and have little to no access, but has this changed since in more recent versions of MOHO? I am using Moho 14.
User avatar
hayasidist
Posts: 3829
Joined: Wed Feb 16, 2011 8:12 pm
Location: Kent, England

Re: Change vector Shapes Fill & Line Color Via JSON

Post by hayasidist »

Overview:
you can scan the list of styles in a doc to make sure you have the ones named in your command file.
you'll need to get the actual M_Style object (Class M_Style)
shapes use the style UUID (not the "display name") so scan all the shapes looking for the UUID of the "to be replaced" style and then update the UUID and Style.
I recall having problems writing to a shape's fInheritedStyleName (its UUID) and updating its fInheritedStyle (the M_style object). I haven't experimented with either for a couple of years. If you choose to try, please let me know if you succeed.


Detail:
this scans the doc's style list

Code: Select all

		local ct = doc:CountStyles()

		for i = 0, ct-1 do
			style = doc:StyleByID(i) -- gets the M_Style

			-- do what you need with the style here - e.g. write it to a table for a subsequent scan of the shapes?? e.g. 
			name = doc:StyleByID(i).fName:Buffer()
			uuid = doc:StyleByID(i).fUUID:Buffer()

		end
You probably don't need to check the style's animation channels -- but ... (e.g.)

Code: Select all

			ch = moho:ChannelAsAnimColor(doc:StyleByID(i).fFillCol)
			colour = ch.value
hope that helps!
User avatar
caderial
Posts: 12
Joined: Mon Jul 08, 2024 8:00 pm

Re: Change vector Shapes Fill & Line Color Via JSON

Post by caderial »

Okay i have it SORT of working, i will eventually need to add a file dialog popup to supply a JSON file that dictates what styles to find and then swap but for ow i'm trying to at least get this rudimentary version working to prove out the concept:
Here is a GDrive Link to my working file: https://drive.google.com/file/d/1FEmaJZ ... sp=sharing https://drive.google.com/file/d/1FEmaJZ ... sp=sharing

Code: Select all

ScriptName = "SimpleStyleSwitcher"
SimpleStyleSwitcher = {}

function SimpleStyleSwitcher:Name() return "Simple Style Switcher" end
function SimpleStyleSwitcher:Version() return "1.0" end
function SimpleStyleSwitcher:Description() return "Switches Skin_Tone_1 to Skin_Tone_2" end
function SimpleStyleSwitcher:UILabel() return "Simple Style Switcher" end

function SimpleStyleSwitcher:ProcessLayer(moho, layer, style1, style2)
    if layer:LayerType() == MOHO.LT_VECTOR then
        local mesh = moho:LayerAsVector(layer):Mesh()
        for j = 0, mesh:CountShapes() - 1 do
            local shape = mesh:Shape(j)
            if shape.fInheritedStyle == style1 then
                shape.fInheritedStyle = style2
            end
        end
    end
    
    if layer:IsGroupType() then
        local group = moho:LayerAsGroup(layer)
        for i = 0, group:CountLayers() - 1 do
            self:ProcessLayer(moho, group:Layer(i), style1, style2)
        end
    end
end

function SimpleStyleSwitcher:Run(moho)
    local doc = moho.document
    local style1, style2
    
    for i = 0, doc:CountStyles() - 1 do
        local style = doc:StyleByID(i)
        local name = style.fName:Buffer()
        if name == "Skin_Tone_1" then style1 = style end
        if name == "Skin_Tone_2" then style2 = style end
    end

    if not style1 or not style2 then
        LM.GUI.Alert("Required styles not found")
        return
    end

    for i = 0, doc:CountLayers() - 1 do
        self:ProcessLayer(moho, doc:Layer(i), style1, style2)
    end
end

function SimpleStyleSwitcher:Init(moho)
    if moho then moho:NewScriptMenu("Simple Style Switcher", SimpleStyleSwitcher) end
end

local function Main()
    if Moho then SimpleStyleSwitcher:Init(Moho) end
end

Main()

However the document has several layers in it each with a few test objects with the original style that is to be swapped for the new style , but the changes only appear on other layers when i click on the layers in the layers panel. (see image attached @ bottom of this message)

I have tried to implement a

Code: Select all

function SimpleStyleSwitcher:RefreshDocument(moho)
    moho.document:SetDirty()
    moho:UpdateAllChannels()
    moho.frame:UpdateCurFrame()
    moho:ForceRedrawAllViews()
    if moho.timeline then moho.timeline:Refresh() end
    if moho.layerpanel then moho.layerpanel:Refresh() end
end
but I get nothing but an error : ...Scripts\Menu\ALERT JEFF 3\SimpleStyleSwitcher.lua:30: attempt to call a nil value (method 'UpdateAllChannels'), even though the color change still happens on the currently selected layer, and then the styles change on subsequent layers one at a time as i click on the layer sin the layers panel. Which is super weird because i have another far more advanced script which parses a scene for the colors of vector objects and changes them to other rgb colors, and updates the scene and all frames int he scene and it works fine using the above forced refresh and updates?!

I have also tried:

Code: Select all

    doc:SetDirty()
    moho.view:DrawMe()
also still not updating the scene unless i click the layers one by one in the layers panel or save and reopen the scene.

Image
User avatar
hayasidist
Posts: 3829
Joined: Wed Feb 16, 2011 8:12 pm
Location: Kent, England

Re: Change vector Shapes Fill & Line Color Via JSON

Post by hayasidist »

I don't know of a "ScriptInterface:UpdateAllChannels()" method.

The closest, ScriptInterface:UpdateSelectedChannels(), doesn't update the Animation Channels -- it updates the display of the "Selected" (red) channels on the timeline (useful when you've changed the items that have been selected)

My guess is that your other script does a MOHO.Redraw() or ScriptInterface:UpdateUI()???

I'll note that you haven't changed the UUID of the styles. This might lead to complications!?
User avatar
caderial
Posts: 12
Joined: Mon Jul 08, 2024 8:00 pm

Re: Change vector Shapes Fill & Line Color Via JSON

Post by caderial »

Okay interestingly enough, if i use the:

moho:UpdateUI()
MOHO.Redraw()
and or the MohoView:DrawMe()

It should update as expected, However it only updates if i Save, Close and reopen the scene, Or if i don't do that, Directly after running the script i can click each layer 1 by 1 in the layers panel and see the updates.

that's odd enough as is, But it turns out. If i move from frame 0 into the timeline, and make some minor changes to each item, such as simply moving them 1 pixel, then keyframes show up, even in frame 0. now if i run the script everything updates and redraws properly across all layers.

I am at a loss as to why frame 0 without keyframes cant redraw or update the view but as soon as i add some keyframes everything acts exactly as i desire...

Thoughts?

Also I have to give you a MASSIVE digital hug and my thanks for being so helpful with me!
User avatar
hayasidist
Posts: 3829
Joined: Wed Feb 16, 2011 8:12 pm
Location: Kent, England

Re: Change vector Shapes Fill & Line Color Via JSON

Post by hayasidist »

odd! -- more frequent "Redraw()" or UpdateUI() - as in every change rather than an the end????
User avatar
caderial
Posts: 12
Joined: Mon Jul 08, 2024 8:00 pm

Re: Change vector Shapes Fill & Line Color Via JSON

Post by caderial »

Thnak you so freaking much hayasidist Seriously, You are a god among us lowly scripters lol

Yeah I have NO idea why it wont do it without any keyframes and in frame 0, Probably a Limitation of the MOHO API

BUT i am okay always ensuring i have some frames even if it is just a static frame in frame 1 so that frame 0 has frames in it.

That being said however I FREAKING DID IT!
I had to first have the script parse through the scene and create an index of StyleIDs and what their correlating StyleNames were, as it would always cause issues trying to find just by StyleName. So basically an array that tracks StyleID=StyleName

Once i had that index, the rest of the script could parse the scene and attribute the ID's properly tot he StyleNames based on the StyleNames supplied by the JSON.

This SIGNIFICANTLY reduces the color changing of my previous attempt where i was searching for rgb values and if i found them ( within a certain tolerance) it would change every shape int he scene to the new rgb defined int he JSON.

ANYWAYS

It works!

IF anywone ends up needing a way to change the STYLES of any object or multiple objects in entire layer stack AND across all animations this is how! create an index of StyleIDs and what their correlating StyleNames then use that array to parse the provided JSON information

In my case:

Code: Select all

{
    "style_changes": [
        {
            "current_style": "Skin_Tone_1",
            "new_style": "Skin_Tone_2"
        },
        {
            "current_style": "Clothing_Base_1",
            "new_style": "Clothing_Base_2"
        }
    ]
}

Post Reply