How do I read the layer structure of a document? (solved)

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
Rasheed
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

How do I read the layer structure of a document? (solved)

Post by Rasheed »

I want to manipulate layers, but how do I read the layer structure into a table? I can't figure out how to do that within a layer script.

Edit: Luckily, with some help I have solved this puzzle myself.
Last edited by Rasheed on Mon Nov 27, 2006 1:52 pm, edited 1 time in total.
User avatar
Rai López
Posts: 2259
Joined: Sun Aug 08, 2004 1:41 pm
Location: Spain
Contact:

Post by Rai López »

Hmmm... HI! I'm not sure if you are reffering to this or you still know this Fazek's post, but if not, maybe it can help you in the same way it helped to me, GOOD LUCK! :D
User avatar
Rasheed
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Post by Rasheed »

Thanks Ramón, I think I can modify that code for my needs.
User avatar
Rasheed
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Post by Rasheed »

Here's the code I have come up with. It reads all layers in a document into a flat array, with the following structure:
  • LayerStruct[n] : the n-th layer in the document (counting from one)
  • LayerStruct[n].parent : the array index number of the parent layer
Here is the fully documented code:

Code: Select all

--**********************************************************
-- layer script to test the LayerStucture function
--**********************************************************
function LayerScript(moho)

    -- read the layer structure
    local LayerStruct = LayerStructure(moho)

    -- print the layer structure
    if ( LayerStruct ~= nil ) then
        for i in LayerStruct do
            print ( i .. ': ' .. LayerStruct[i]:Name() 
            .. ' (parentID = ' .. LayerStruct[i].parent .. ')' )
        end
        print ( 'done' )
    end
    
end

--**********************************************************
-- read and return the layer structure as an array
--
-- the array is layed out as follows:
-- [i]          reference to the layer in moho
-- [i].parent   index number of the parent layer (0 = no parent)
--
-- Note: in Lua we count in arrays from one, not from zero
--
-- Based on the layer scan routine by Fazek
-- see: http://www.lostmarble.com/forum/viewtopic.php?p=23651#23651
--
-- this function creates two global variables:
--      LayerStruct
--      LayerDocCount
--**********************************************************
function LayerStructure(moho)
    
    local document = moho.document
    
    -- if there are no layers in the document, then return a nil value
    local LayerCount = document:CountLayers()
    if ( LayerCount == 0 ) then
        return nil
    end
    
    LayerStruct = {}    -- global table, array of layers and parentIDs
    LayerDocCount = 1   -- global variable, number of layers in document
    
    -- put all root level layers in the document into an array
    -- use index value zero to indicate there are no parent layers
    -- increment the index counter by one
    for i = 1, LayerCount do
        local layer = document:Layer(i - 1)
        LayerStruct[LayerDocCount] = layer
        LayerStruct[LayerDocCount].parent = 0
        LayerDocCount = LayerDocCount + 1
            
        -- if the current layer is a group type layer,
        -- then add the child layers (and their child layers and so on)
        -- use the layer's index counter value as parent index value
        if ( layer:IsGroupType() ) then
            local parent = moho:LayerAsGroup(layer)
            AddOffspring(moho, parent, LayerDocCount - 1)
        end
        
    end
    
    -- return the complete layer structure as an array
    return LayerStruct
        
end

--**********************************************************
-- recursive function to add the layer structure within a group type layer
-- to the global array 'LayerStruct'
--
-- parentGroup is the parent layer as group layer
-- parentID is the value of the global index counter of the parent layer
--**********************************************************
function AddOffspring(moho, parentGroup, parentID)
    
    -- if there are no layers inside the current group type layer,
    -- then return (no child layers present)
    local LayerCount = parentGroup:CountLayers()
    if ( LayerCount == 0 ) then
        return
    end

    -- for all layers within this group type layer,
    -- add the layer to the next array element of LayerStruct,
    -- and add the index counter value of the parent group type layer
    -- as the parent value
    -- increment the global index counter by one    
    for i = 1, LayerCount do
        local layer = parentGroup:Layer(i - 1)
        LayerStruct[LayerDocCount] = layer
        LayerStruct[LayerDocCount].parent = parentID
        LayerDocCount = LayerDocCount + 1

        -- if the current layer is a group type layer,
        -- then add the child layers (and their child layers and so on)
        -- use the layer's index counter value as parent index value
        if ( layer:IsGroupType() ) then
            local parent = moho:LayerAsGroup(layer)
            AddOffspring(moho, parent, LayerDocCount - 1)
        end
    end
    
end
I really don't like two things about this solution:
  1. two functions instead of one
  2. global variables, 'LayerStruct' and 'Index'
If I could write these two functions as one, I wouldn't need to use a global variable. I just have to keep puzzling on this... :?
User avatar
Rai López
Posts: 2259
Joined: Sun Aug 08, 2004 1:41 pm
Location: Spain
Contact:

Post by Rai López »

...EY Rasheed! That is SO interesting! And definitelly could become Embedded scripts in a more versatile/useful/easy feature, well I'll do a deep study of all that succulent lines when I return of work, you can be sure! It remember so much to that days when you wrote that marvelous Embedded Scripts tutorials :roll: ...And BTW, even (maybe) it could help me whith :arrow: this, I don't know yet but I hope, I must study it more as I said, specially the ID parts... Well, now I must go to work :( ...THANK YOU FOR ALL!!!
Last edited by Rai López on Tue Nov 28, 2006 4:30 am, edited 1 time in total.
User avatar
Rasheed
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Post by Rasheed »

Well, I haven't looked into your problem yet (I had planned to, though). So now I will do that and see I an extra pair of brains can solve your problem.

BTW Losing sleep over a simple problem is quite normal IME. Perhaps that is why geeks have size XXL from eating too many nachos and cola ;)
User avatar
Rasheed
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Post by Rasheed »

For some reason the script I published earlier doesn't do what it is supposed to do. So I rewrote the function and got rid of the global variables. It is still a two part function (LayerStructure and AddOffspring). I left out the commenting, because I didn't want to do that at this stage of development.

Code: Select all

function LayerScript(moho)

    local layerStruct = LayerStructure(moho)

    if ( layerStruct ~= nil ) then
        for i in layerStruct do
            print( i .. ': ' .. layerStruct[i]:Name() 
            .. ' (parentID = ' .. layerStruct[i].parent .. ')' )
        end
    end
    
end

-- Return the layer structure of the document
-- works in conjuction with the AddOffspring function
function LayerStructure(moho)
    
    local document = moho.document
    
    local layerCount = document:CountLayers()
    if ( layerCount == 0 ) then
        return nil
    end
    
    local layerStruct = {}
    local structIndex = 1

    
    for i = 1, layerCount do
        local layer = document:Layer(i - 1)
        layerStruct[structIndex] = layer
        layerStruct[structIndex].parent = 0
        structIndex = structIndex + 1
            
        if ( layer:IsGroupType() ) then
            local parent = moho:LayerAsGroup(layer)
            layerStruct, structIndex 
            = AddOffspring(moho, parent, layerStruct, structIndex)
        end
        
    end
    
    return layerStruct
        
end

-- recursive function to find the sub layers of the layer structure
function AddOffspring(moho, parent, layerStruct, structIndex)
    
    local parentID = structIndex - 1
    local layerCount = parent:CountLayers()
    
    if ( layerCount > 0 ) then
    
        for i = 1, layerCount do
            local layer = parent:Layer(i - 1)
            layerStruct[structIndex] = layer
            layerStruct[structIndex].parent = parentID
            structIndex = structIndex + 1
            
            if ( layer:IsGroupType() ) then
                local parent = moho:LayerAsGroup(layer)
                layerStruct, structIndex 
                = AddOffspring(moho, parent, layerStruct, structIndex)
            end
        end
    end
    
    return layerStruct, structIndex
    
end
Post Reply