Archive site for Autodesk Ecotect Analysis educational resources, notes and tutorials



Script example 09

ObjectOrientedRef.scr

This script is an interesting use of table tags in LUA to allow direct access to ECOTECT model data in a way similar to object-oriented classes. By over-riding the gettable functions, it is possible to intercept references to entries in some global tables and pre-populate them with data corresponding to the actual entity in the ECOTECT data model.

This means that it is possible to access details about the 2nd zone by using the nomenclature eco.zone[2]. Thus, you could use:

-- New access format.
pt = eco.object[1].node[4].pos
print(eco.zone[2].volume)

instead of:

pt = {} -- Existing access format.
pt.x, pt.y, pt.z = get("object.node.position", 1, 4)
print(get("zone.volume", 2))

The following code demonstrates read-only data access for zones, objects and nodes. Materials, schedules and other entities will be added soon, as will setting property values. In fact, this nomenclature will likely be added as the standard means of referencing ECOTECT data in version 6.0 in the future.

Script Contents (Lang: lua)

-- --------------------------------------------
-- This script allows you to access ECOTECT data
-- as objects int your scripts. For example, you
-- can use the following notation:
--     eco.zone[4].volume
--     eco.object[15].area
--     eco.object[15].node[3].pos.y
--     eco.node[3].pos.y
-- --------------------------------------------

-- [[header-start]] --

_EcoTag_Main = newtag()
_EcoTag_Tables = newtag()

-- This function manages model data.
function _EcoGetTableData(table, index)

    -- Check for metadata and get value.
    local metadata = rawget(table, "_metadata");
    local value = rawget(table, index);

    -- Return an existing value.
    if type(value) ~= "nil" then 
        return value
    end

    -- Check for table[index].
    if type(index) == "number" then 

        -- Check for object.node table.
        if metadata["type"] == "node" then
            if type(metadata["offset"]) == "number" 
              and metadata["offset"] > 0 then
                index = index + metadata["offset"]
            end
        end
    
        -- Compare with existing index.
        if index ~= metadata["index"] then

            -- Application data.
            if metadata["type"] == "zone" then 

                table = getZoneData(index)

            elseif metadata["type"] == "object" then 

                table = getObjectData(index)

                table.node = { 
                    ["_metadata"] = { 
                        ["type"] = "node", 
                        ["offset"] = table.firstNode 
                        } 
                     }

                settag(table.node, _EcoTag_Tables)

            elseif metadata["type"] == "node" then 

                table = getNodeData(index) 
                table.node = nil

            end

            -- Metadata.
            table["_metadata"] = {
                ["type"] = metadata["type"],
                ["index"] = index
                }

        end

        return table

    end

    return nil

end


-- This function manages the 'eco' table.
function _EcoManageMainTable(table, index)

    local value = rawget(table, index);

    -- Check for existing value.
    if type(value) ~= "nil" then 
        return value
    end

    -- Check to create child tables.
    if type(index) == "string" then 

        -- eco.zone.
        if index == "zone" then

            if type(value) ~= "table" then

                table.zone = { 
                    ["_metadata"] = { 
                        ["type"] = "zone" 
                        } 
                    }

                settag(table.zone, _EcoTag_Tables)

            end

            return table.zone

        -- eco.object.
        elseif index == "object" then
        
            if type(value) ~= "table" then

                table.object = { 
                    ["_metadata"] = { 
                        ["type"] = "object" 
                        } 
                    }

                settag(table.object, _EcoTag_Tables)

            end

            return table.object

        -- eco.node.
        elseif index == "node" then
        
            if type(value) ~= "table" then

                table.node = { 
                    ["_metadata"] = { 
                        ["type"] = "node" 
                        } 
                    }

                settag(table.node, _EcoTag_Tables)

            end

            return table.node

        end

    end

    return nil

end

-- Create table management tags.
settagmethod(_EcoTag_Tables, 'gettable', _EcoGetTableData)
settagmethod(_EcoTag_Main, 'gettable', _EcoManageMainTable)

-- Create the main table and
-- associate it with the tag.
eco = {}
settag(eco, _EcoTag_Main)

-- [[header-stop]] --

-- This is a useful function for
-- iterating through table data.
function print_table(table, prefix)

    if prefix == nil then
        local metadata = rawget(table, "_metadata");
        if type(metadata) == "table" then 
            prefix = metadata["type"]
        else 
            prefix = "" 
        end
    end

    for key, value in table do
        if type(value) == "table" then 
            print_table(value, prefix .. "." .. key)
        else 
            print (prefix .. "." .. key .. "=" .. value) 
        end
    end

end

-- Some example usage.
printf("AREA 1: %0.3f", eco.object[1].area)
printf("AREA 1: %0.3f", eco.object[2].area)
printf("VOLM 1: %0.3f", eco.zone[1].volume)
print("\n=====================================\n\n")
print_table(eco.object[1].node[4])
print("\n=====================================\n\n")
print_table(eco.object[1])
print("\n=====================================\n\n")
print_table(eco.zone[1])

HOW WOULD YOU RATE THIS SCRIPT ?

Average: 4 (1 vote)


Navigation

User login

Translate Site To: