Placing Objects

This very first script is explained and commented on in detail to give you an idea of how to write a script. While creating a program, it is absolutely important to have a plan and a concept, because without these you will hardly ever get the desired result, especially as a beginner. With growing experience and short scripts it is not always to necessary to create a complete syntax structure, but for more complex programs it is mandatory.

 

Name

Objects2Vertices.rfs

Type

Batch script

Description

This script reads out the vertices of all objects in the scene and writes them into a list. The position data are then used to place a certain object at the vertices location. These objects will be created automatically.

 

What the script should do:

  1. Detect all objects inside the current scene
  2. Loop through the objects, collect the vertices, and store them inside a list
  3. Get the position data
  4. Add the clone object which is placed at the source node’s vertices
  5. Find the name of the cloned objects to reposition them
  6. Transfer the vertex positions to the objects and scale them

 

For getting the objects in a scene, RealFlow provides several options. If you want to get all objects, there is the statement:

getObjects()

 

It reads everything that consists of vertices and polygons. If you want to restrict the script to a certain selection you have made in the "Nodes" window, then you have to use

getSelectedNodes()

 

In this case it is recommended to check whether the chosen item really is an object, and not an emitter or a daemon. Both methods are a property of the scene class, so the complete notation is:

scene.getObjects()
scene.getSelectedNodes()

 

So far, so good, but currently the nodes are not stored and cannot be used for further manipulation. You have to assign a variable to store the elements. The statements tell Python that there can be more than one object and this means that everything is written to a list. Lists are able to store more than one value and each entry can be identified by its position inside the list – the index starts at 0. RealFlow automatically detects if a list variable is required, but there are also many situations where you have to introduce a variable manually to initialize it. In such a case it is up to you which data type is needed. RealFlow’s help shows the required data type for each known statement and instruction:

Object[] getObjects()
Node[] getSelectedNodes()

 

This notation indicates that getObjects() will only catch true objects and write them to a list, which is represented with square brackets. getSelectedNodes() does not distinguish between node types – all nodes  are written to the list and it is up to you to sort out which one you can use. Just a tip: The getType() instruction will help you out here.

Since this script should only use true objects, the getObjects() statement is the best choice. Whenever there is more than one element inside a list you have to create a loop to make them accessible. The for … in loop will perfectly serve your needs, but before it can be executed, a counter variable has to be introduced and finally incremented:

counter = 1
scene_objects = scene.getObjects()

for single_object in scene_objects:
    do something here...
    counter += 1

 

The next step is to get the vertices from each single_object and the individual positions. Again there is more than one element, so the next variable will be a list, too:

Vertices[] getVertices()

 

Of course, it again requires a loop to read the individual positions from each vertex, so the entire construction for this purpose is:

counter    = 1
objectList = scene.getObjects()

for single_object in objectList:
    vertexList = single_object.getVertices()

    for single_vertex in vertexList:
        vertex_position = single_vertex.getPosition()

 

The result from this second loop is vertex_position , which is a  vector – what you receive from getPosition() is a trio of three values for the X, Y and Z coordinates, which is considered a “vector” in RealFlow. This vector will then be used as a reference for the clone objects. To proceed, an object is needed for each vertex – here it is a sphere, but you can choose any other object. Creating objects is a little bit different from adding emitters or daemons, because each object has its own statement:

addSphere()

 

If you want to add another object type, you can write: addCube(), addTorus(), addRocket() and so on. Once it is created, RealFlow assigns a new name to it, for example “Sphere01”, “Sphere23”, “Sphere175” etc.

The task now is to automatically find a pattern to read this name, because it must be used to clearly identify the appropriate object. Otherwise it is not found by RealFlow and you receive a syntax error. In this example it is not too difficult, because each object starts with “Sphere” followed by an index. Since  the enumeration is not 1, 2, 3, 4,.., but 01, 02, 03, 04,... a differentiation is needed, and that is why a counter has been introduced at the beginning of the script. Here is the function:

scene.addSphere()

if (counter < 10):
    cloneObject_name = "Sphere0"+str(counter)

else:
    cloneObject_name = "Sphere"+str(counter)

cloneObject = scene.getObject(cloneObject_name)
counter += 1

 

Unless the counter has reached 10, the name should be written as 01, 02, 03, 04 and so on. For this purpose the leading 0 is used and then combined with the string value of the counter: str(counter). With the “+” operator both elements are assembled together. Once 10 has been reached, the name just corresponds with the counter. Now the appropriate clone object can be identified. Finally it is necessary to translate the current vertex positions to a clone object and rescale it: 

cloneObject.setParameter("Position", vertex_position)
scaleVector = Vector.new(0.2, 0.2, 0.2)
cloneObject.setParameter("Scale", scaleVector)

 

The last two lines can also be written as:

cloneObject.setParameter("Scale", Vector.new(0.2, 0.2, 0.2))

 

And that is all. To run this script, add one or more objects to your scene, open a batch script window, and copy/paste (mind tabs and indents!) or re-type the code to this window and choose:

Script > Run

You now can see how the clone objects are created and distributed to the vertices of the existing objects. The cubes on the right were dyed with a little script, adding random colours to the nodes. You should already be able to write this extension.

 

 

Here is the entire listing: 

# Batch script

counter    = 1
objectList = scene.getObjects()

for single_object in objectList:
    vertexList = single_object.getVertices()

    for single_vertex in vertexList:
        vertex_position = single_vertex.getPosition()
        scene.addSphere()

        if (counter < 10):
            cloneObject_name= "Sphere0"+str(counter)

        else:
            cloneObject_name = "Sphere"+str(counter)

        cloneObject = scene.getObject(cloneObject_name)
        cloneObject.setParameter("Position", vertex_position)
        cloneObject.setParameter("Scale", Vector.new(0.2, 0.2, 0.2))
        counter += 1