[SESI logo]

Houdini Development Toolkit - Version 5.1

Side Effects Software Inc. 2002

Vex Builder

VOP Coding Standard


To make it easy for the users of VOPs to work with these operators, we need to ensure that all VOPs have a consistent look and feel. This document defines a set of coding and interface rules to be observed by all VOP programmers.
 

  • Inputs
  • Outputs
  • Parameters
  • Scripted Subnetworks
  • Help Text
  • Icons

  • Inputs

    Never use the name of a global variable to define an input variable unless the input defaults to a global variable if not connected. For example, use "pos" instead of "P" if "P" is not assumed. Refer to the table below for several examples.
     
    Global Variable Local Variable
    P pos
    Cf color
    Of opacity
    Af alpha
    s u
    t v
    N nml

    If the input defaults to a global variable when not connected, you must use the name of that variable in the input. For example, use "s" instead of "u" if "s" is assumed.

    All variable names must be lower-case unless the input defaults to a global variable that has an upper-case name.

    Avoid using underscores in the variable names because shorter names fit better on the tile input buttons.

    Order the inputs by their intrinsic names rather than by their "s" and "t" association. For example:
     

    Correct Order Incorrect Order
    sjitter
    tjitter
    srough
    trough
    sjitter
    srough
    tjitter
    trough

    Qualifiers such as "s", "t" should appear in the name prefix, not the  suffix. For example, "tjitter" is correct, but "jittert" is incorrect.

    Always order the inputs so that any potential global variables appear first.

    If the VOP expects a normalized vector as its input, you must prefix the name of the vector with "n". For example, if a VOP requires a normalized "vec" input, it should list that input as "nvec". You will often see the "nN" input name in our VOPs. That means that the VOP will use the global N if no input is provided (and will normalize it internally); but if an input exists, it must be normalized before being plugged into the VOP.

    Look at existing VOPs to decide on the name of a typical input. For example, if you wonder whether to name the Roughness parameter "rough" or "roughness", look in many of the noise functions to see what name we have used.

    Names up to 7 characters long will fit well onto the tile button. Be generous with respect to name lengths. Cryptic names might not make much sense even to fellow programmers, not to mention our users.
     
     

    Outputs

    Never use the name of a global variable to name an output variable even if you intend the output to be piped into an Output VOP .

    If the input is a global variable and the output a modified copy of that variable, the output name should prefix the global name by a label indicative of the operation. For example, if the VOP displaces "P", the output name could be
    "dispP".

    Use "new" rather than "out" to prefix an output variable name when you cannot think of a more descriptive label. For example, "newdir" and "newP" would be valid, if not very descriptive, names.

    If the output is a normalized vector, prefix its name with "n", as in "nvec".

    All variable names must be lower-case unless the output modifies a  global variable that has an upper-case name.

    Avoid using underscores in the variable names because shorter names fit better on the tile input buttons.

    Names up to 7 characters long will fit well onto the tile button. Be generous with respect to name lengths. Cryptic names might not make much sense even to fellow programmers, not to mention our users.
     
     

    Parameters

    Not all inputs should have parameters in the VOP dialog. If an input is optional, i.e. a [global] variable is used  by default if the input is not connected, that input should not have a parameter.

    If you are writing the .ds file as code rather than using the GUI (where applicable), include <parameter.ds> at the top
    of the file and rely on its macros to define the inputs for maximum conciseness. Compare the two snipets of equivalent code:
     

    #include <parameter.ds> Without parameter.ds
    VOP_VEC_INPUT(pivot, "My Pivot",  0,0,0) input vector pivot "My Pivot"
    parm {
          name    pivot
          label   "My Pivot"
          type    float
          size     3
          default { 0, 0, 0 }
    }

     
     

    Code and Outer Code

    Keep the Code section of the .ds file as simple as possible.

    Use the Outer Code section to implement reusable functions.

    Include <voplib.h> into the Outer Code section to take advantage of low-level functions used by many existing VOPs.

    Never define an unbound parameter in the code.

    If you are doing a subtraction, leave a space around the minus sign. If you don't, and someone enters a negative number, the generated code will contain a "--", which chokes vcc.

    Take advantage of the automatically generated "$isconnected" variables to write code that does different things if a given input. Here is an example of how the Ray Trace VOP (raytrace.ds) does it:

    code {
        "vector $myP = $isconnected_P ?  $P : P;"
        "trace($color, $opacity, $alpha, $myP, $ndir, $bias, $maxcontrib);"
    }
    Take advantage of the automatically generated "$signature" variable in VOPs that support multiple signatures. Using $signature in a #if-#elif-#else-#endif  structure allows you to write different code (i.e. not just polymorphic code) for each signature. Take a look at Anti-Aliased Noise (aanoise.ds) for a good example. Here's an excerpt from it:
    code {
        "if !strcmp($signature, \"default\")"
        "    $noise = vop_fbmNoiseFV(.....);"
        "#else"
        "    $noise = vop_fbmNoiseVP(.....);"
        "#endif"
    }
     
     

    Scripted Subnetworks

    Replace the default VOP labels in the subnet with descriptive names where applicable.

    Enter comments in the more important VOPs of the network if applicable.

    Never use the Parameter VOP inside a subnet unless you toggle on the option to "use the input value if parameter is not bound".

    Make sure the nodes in the subnet have a decent layout. The automatic node placement algorithm is rarely useful.
     
     

    Help Text

    Always provide enough help to make the VOP usable. Never leave a VOP without help, no matter how trivial the operator.

    The first paragraph should offer nothing more than a brief description of the functionality.

    If time allows, provide full documentation of each input, output, and intrinsic parameter. (An intrinsic parameter is a parameter without an input.). See the help for the Parameter VOP for a good example.

    Provide one or two useful tips suggesting good parameter values and ways to connect the VOP to inputs and outputs.

    If an input is expected to be normalized, mention it. Also, mention if a global variable is used as a substitute for a non-connected input. Displace Along Normal offers a good example of how to document these facts:

    The input normal (N) should be normalized if explicitly connected. If the position (P) and normal (N) inputs are not connected, the global variables by the same names will be used instead.
    Here is a snipet of code from the same VOP to further clarify how the VOP deals with those inputs:
    vector $nn = $isconnected_nN ? $nN : normalize(N);
    vector $pp = $isconnected_P ? $P : P;
    Always make sure the help text ends with a "See also: " entry.
     
     

    Icons

    Use iconsmith or gicon to make icons for low-level and intermediate-level VOPs.

    Produce 64x64 pic files for high-level VOPs.
    You can use the attached hip file to generate pic icons. The switch SOP in the shader_geo object allows you to choose a sphere, a tube, a grid or a torus for display. Display either the grey_walls object or the checkered_walls object if you want walls behind the shaderball. Use the headon_mantra output driver to render the image.
     


    Copyright © 2002 Side Effects Software Inc.
    477 Richmond Street West, Toronto, Ontario, Canada M5V 3E7