Create more complex nodes

Now that we have gone through the exercise of creating some simple nodes, it’s time to create a more complex node. To this end a deformer would be a good example, as it’s a fairly common use case.

In the Node Description Editor, please click on File -> New Node to start the creation process for a new node:

../../../../_images/tutorial1_3_9.png

Fill in the node details as follows:

../../../../_images/tutorial1_4_1.png ../../../../_images/tutorial1_4_2.png ../../../../_images/tutorial1_4_3.png

Note that key difference is that for the in_points attribute we’re tagging it with a tuple size of 3, and making it an array (it’s also of type float, as opposed to double, as that tends to be the default data for point arrays in the USD sample we have).

From here generate the .ogn file and sample implementation file as we have done for the other nodes in the previous tutorial.

Open the OgnTestDeformer.py implementaion file and fill in its contents like so:

"""
This is the implementation of the OGN node defined in OgnTestDeformer.ogn
"""
# Used for the sine function
import numpy


class OgnTestDeformer:
    """

    """
    @staticmethod
    def compute(db) -> bool:
        """Compute the outputs from the current input"""

        try:
            multiplier = db.inputs.multiplier

            points = db.inputs.in_points

            wavelength = 2
            offset = 3.14

            db.outputs.out_points_size = points.shape[0]
            # Nothing to evaluate if there are no input points
            if db.outputs.out_points_size == 0:
                return True

            pt = points.copy()  # we still need to do a copy here because we do not want to modify points
            tx = pt[:, 0]
            offset_tx = tx + offset
            ty = pt[:, 2]

            disp = (numpy.sin(offset_tx/wavelength) )
            pt[:, 1] += disp * multiplier

            db.outputs.out_points[:] = pt[:]  # we modify output_points in memory so we do not need to set the value again
        except Exception as error:
            # If invalid data caused the compute to fail then report it
            db.log_error(f"Could not deform the points - {error}")
            return False
        return True

Notice that arrays are bound to numpy - this allows us to have our internal buffers bound to Python without having to copy it, and also allows us to use numpy syntax and functionality for manipulating these arrays.

Now that the node is ready, let’s wire it up in the graph. Start with creating two prim nodes, by dragging and dropping PolyMeshPlane_in and PolyMeshPlane_out into the Graph Editor:

../../../../_images/tutorial1_4_5.png

Proceed to place one of our TestDeformer nodes and wire it up like so:

../../../../_images/tutorial1_4_6.png

Now, as you move the sphere around, the plane should deform, like so:

../../../../_images/tutorial1_4_7.png