What is the best way to iterate over objects in Ecotect ?

I see that I can simply cycle through all object in the model, but sometimes I want only certain types or just selected objects. Are there easier and quicker ways of doing this ?

One of the tasks you often need to do in an Ecotect script is iterate over objects within the model. This could just be to count all the DOOR elements or you may need to calculate the total area of all FLOOR objects. The example functions shown here illustrate different ways to do this depending on whether you want all objects or those of a certain type, on a certain zone or just from the current selection set.

Iterating Through Objects

The easiest way to cycle through all objects in the model is to use a simple for loop.

function CycleAllObjectsInModel()
  objCount = get("model.objects") - 1
  for objIndex = 0, objCount do
    -- Do what you need to do here with objIndex.
  end
end

Iterating Over Certain Object Types

When looking for only specific types of objects, it is quicker to use the model.nextobject method and supply the right parameters. This command has the following format.

get("model.nextobject", startAt, elemType, flags, tags, zone)

Thus, we need to start the search using -1 (otherwise it would ignore the first object with index 0) and specify an elemType of 4, which corresponds to a wall. As we don't want to specify any of the other parameters, we give them as -1.

function CycleAllWallObjectsInModel()
  objIndex = -1
  repeat -- Cycle though all WALL(4) objects in model.
    objIndex = get("model.nextobject", objIndex, 4, -1, -1, -1);
    if objIndex >= 0 then
      -- Do what you need to do here with objIndex.
    end
  until (objIndex < 0)
end

Iterating Over Visible Objects

To check for objects that are visible, we need to check the zone they belong to first. Doing this is easier if we do it zone-by-zone rather than having to seek out and check the zone for each object. Thus, the following shows two functions needed to do this.

function CycleAllObjectsInZone(zone)
  objIndex = -1
  repeat
    objIndex = get("model.nextobject", objIndex, -1, -1, -1, zone);		
    if objIndex >= 0 then
      -- Do what you need to do here with objIndex.
    end
  until (objIndex < 0)
end

function CycleAllVisibleZones()
  zoneCount = get("model.zones") - 1
  for zone = 1, count do
    if get("zone.hidden", zone) < 1 and get("zone.off", zone) < 1 then
      CycleAllObjectsInZone(zone)
    end
  end
end

Iterating Selected Objects

When dealing with the current selection set, you can use the selection object instead of the model object. With this change, the format for iterating over them is pretty much the same, as shown below.

function CycleSelectedObjects()
	
  objIndex = -1;
  objCount = get("selection.count")	
  for i = 1, objCount do
	
    -- Starting at -1, get next object index.
    objIndex = get("selection.next", objIndex);
		
    if objIndex >= 0 then
      -- Do what you need to do here with selected object.
    end
	
  end

end

Temporarily Storing the Selection Set

Sometimes you will want to perform operations on individual objects that will themselves affect the current selection set. For example, you may want to extrude each of the selected objects. As soon as you apply that operation to the first object, the selection set will change to become the extruded objects you just created.

An easy way to deal with this is simply to store the indexes of all selected objects in an array at the very start of your script. Then you can whatever you like within the script itself, knowing that you have the original list. An example of this is given below.

function StoreSelectedObjectsAsList()

  objArray = {}
  objCount = get("selection.count")
  objIndex = -1;
  objInc = 0;

  -- Add selected object to array.
  for i = 1, objCount do
	
    -- Starting at -1, get next object index.
    objIndex = get("selection.next", objIndex);
    if objIndex >= 0 then
      objInc = objInc + 1 -- Increment first so that array index starts at 1.
      objArray[objInc] = objIndex
    end
	
  end

  return objArray;

end


function CycleObjectsInList(objectList)

  -- Cycle through array items.
  for i = 1, getn(objectList) do
	
    objIndex = objectList[i]
		
    -- Check for valid object.
    if objIndex >= 0 then
      cmd("select.index", objIndex) -- Select the object.
      -- Do what you need to do here with selected object.
    end
	
  end
	
end

-- Store selected object indexes in a global array.
initiallySelectedObjects = StoreSelectedObjectsAsList();	

-- Do stuff here that might 
-- affect the selection set.
cmd("select.none")

-- Now act on previous selection set.
CycleObjectsInList(initiallySelectedObjects)



View desktop or mobile version of site.