[SESI logo]

Houdini Development Toolkit - Version 6.5

Side Effects Software Inc. 2004

Question & Answers

  1. Is there an archive of the development kit mailing list?

    You can subscribe to the developer mailing list by sending mail to sidefx-devkit-list-request@sidefx.com or sidefx-devkit-list-archive@sidefx.com with the following in the body of the message:

    subscribe

    There is an archive of past mail which can be found at the technical support web page. A password is required to access this site. By not entering a correct password, instructions for acquiring a password will be presented.

    At the current time, the mailing list has very very low bandwidth.

  2. Do I need the C++ development option from SGI? Or can I use another C++ compiler (like GNU)?

    You must use the SGI C++ development option. We are currently using the 4.0 version of the IDO.

    The Photon C++ compiler supposedly works as a replacement for the SGI compilers, but we currently believe that there are problems creating .so files with this compiler.

    For WindowsNT development, the Microsoft C++ compiler is required.

  3. What does the findPointAttrib() method do?

    Our geometry library allows arbirtrary attributes on points/vertices/primities and the detail itself. Each attribute may be an array of floats, integers, a vector (which gets transformed) or an indexed array of strings.

    Looking in GEO_Detail.h, you'll see a bunch of methods to deal with attributes:

    Add an attribute to a data type
  4. addPointAttrib()
  5. addPrimAttrib()
  6. addVertexAttrib()
  7. Find an attribute if it exists
  8. findPointAttrib()
  9. findPrimAttrib()
  10. findVertexAttrib()
  11. Destroy an attribute
  12. destroyPointAttrib()...
  13. The add/find methods return an index for the attribute. If the index is >= 0, then the attribute exists, and the index can be used to get the attribute data... For example:

    int color; float ones[3]; ones[0] = ones[1] = ones[2] = 1; color = gdp->addPointAttrib("Color", sizeof(float)*3, GB_ATTRIB_FLOAT, (void *)ones); The above code adds an attribute called "Color" which is considered to be 3 floating point numbers. The initial value for the attribute data is set to {1,1,1} (based on the default passed in). This means, that whenever a point gets added, it will have its color initialized to 1,1,1. Now, what we'll want to do is assign values to the attribute data for the data elements...

    int i; GEO_Point *ppt; float *cptr; // Pointer to the color data for (i = 0; i < gdp->points().entries(); i++) { ppt = gdp->points()(i); // Use the index that we were returned in the example // above cptr = (float *)ppt->getAttribData(color); cptr[0] = ....; cptr[1] = ....; cptr[2] = ....; } If we want to destroy the attribute:

    gdp->destroyPointAttrib("Color", sizeof(float)*3, GB_ATTRIB_FLOAT);
  14. How are ranges set for slider gadgets? I've been noodling through PRM_Range, and PRM_Template, but an example would be so much clearer for a neophyte.

    If you look at the constructor for PRM_Template, you'll see:

    PRM_Template(PRM_Type thetype, PRM_Name *thenameptr, PRM_Default *thedefaults, PRM_ChoiceList *thechoices, PRM_Range *therange, PRM_Callback thecallbackfunction, void *thespareptr) So, simply define a range, and pass it in when you define your template for the parameter. Here's an example:

    static PRM_Range range(PRM_RANGE_RESTRICTED, 0, PRM_RANGE_UI, 100) This defines a range which is totally restricted to a minimum value of 0. When you evaluate the parameter, it will never return a negative number. The upper limit of the range is set to 100. This is a "UI" range. In other words, the user can override the slider and enter a number bigger than 100.

    To reference this range:

    PRM_Template(PRM_FLT_J, 1, &myName, 0, 0, &range);
  15. Why don't my gadgets show up? I've extended myTemplateList[] and names[], but they don't appear.

    When Houdini creates your SOP the very first time. It creates a UI file which defines the layout of the parameters. It's possible for you to customize this layout if you like by editing the UI file.

    However, Houdini isn't smart enough to time-stamp the UI files, therefore, if you change your parameter list, you have to remove the UI file so that Houdini will create a new one (similar to dialog scripts).

    These UI files are created somewhere writable in your Houdini search path. The files are created as high up as possible in the path, so look for the files in:

  16. $HFS/houdini/config/Dialogs/*/opname
  17. /usr/local/houdini/config/Dialogs/*/opname
  18. $HOME/houdini/config/Dialogs/*/opname
  19. $HIP/houdini/config/Dialogs/*/opname

  20. or if all else fails, these UI files will be created in /usr/tmp/Dialogs.

  21. How do I determine if an OBJ_Node * refers to a geometry object or a null object? In fact, a null object is identical to a geometry object (they use the same templates for construction). However, the null object has a different parameter set displayed in the UI file. This was done by customizing the UI file.

    The way to differentiate between the two similar OPs is to get at the OP_Operator entry. There is a method in OP_Parameters::getOperator() which returns a pointer to the operator. From this, you can get at the name of the operator.

    OP_Operator *entry; entry = obj->getOperator(); if (entry->getName() == "null") cerr << obj->getName() << " is a null object\n"; else cerr << obj->getName() << " is a " << entry->getName() << " object\n";
  22. How do I do variable expansion on a string? And how do I determine if it's changing over time?

    There's some misleading code in PRM_Parm.h. The isTimeDependent() method actually only works for animated parameters (not strings). However, there's a method in the CH_Manager class which will expand strings for you. It returns an inteteger 1 if the string is time dependent. So, instead of evaluating the parameter as an expanded string, evaluate it without expansion. Then simply call the channel manager to do the expansion for you and use the return code to determine whether the string is time dependent.

    UT_String raw_string, expanded; OBJ_Node *node; obj->evalString(raw_string, "ri_shader", 0, now, 0); if (OPgetDirector()->getChannelManager()->expandString( raw_string, expanded_string, now, obj->getChannels())) { cerr << "ri_shader changes over time for " << obj->getName() << endl; }
  23. I've just added some custom expressions. How do I add help in the textport for them?

    If you look in $HFS/houdini/help, you should see two files, exprhelp, and command.help. These are simple ASCII files which contain help (in different formats) for expressions and commands. Instead of modifying the help in $HFS, you can create a smaller file which contains only the help for your commands. This file can go anywhere within the Houdini search path (i.e. /usr/local/houdini/help, $HOME/houdini/help, $HIP/houdini/help, etc.). The help files are all merged together when displaying help.

  24. How can I force my OP to be frame dependent (i.e. whenever the frame changes, I want my OP to cook, even if there are no channels)?

    In the cook method, simply add the following line:

    OP_Node::flags().timeDep = 1; This has to be set every time the OP cooks since it's possible for the dependency to change from time to time.

  25. My SOP doesn't load into Houdini. This is most likely due to a DSO error. An external library may not be referenced properly, there might be missing symbols in the DSO etc. On SGI's try setting the environment variable % setenv HOUDINI_DSO_ERROR This will cause DSO errors to be printed to the window shell when the DSO is accessed. They should appear if you run hscript or houdini.


Table of Contents
Operators | Surface Operations | Particle Operations | Composite Operators | Channel Operators
Material & Texture | Objects | Command and Expression | Render Output |
Mantra Shaders | Utility Classes | Geometry Library | Image Library | Clip Library
Customizing UI | Questions & Answers

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