HDA class outline.

HDA class.

Date Created:Saturday August 02nd, 2008 04:23 PM
Date Modified:Saturday August 02nd, 2008 04:23 PM


- ls, cd, cp and houdini commands

- creating parameters
* Promoting parameters directly from a node.
* Promoting parameters from Parameter Browser inside of Type Properties.
* Making a parameter from scratch, and using `ch()` to link parameters.
* Creating a persistant Handle.
- disabling parameters
*AND & OR statements
# if parm is 0 or parm1 is 0 and parm2 is 1
{ parm 0 } { parm1 0 parm2 1 }

- hidden parameters and their benefits

1) Start a new session of Houdini and navigate inside of a Geometry Object.

If you do not have the default scene, hit the tab key and type Geometry, select it from the menu, and Drop it Down. Jump inside by hitting the enter key. (you may also use the hotkey u)

2) Drop Down an L-system SOP from the tab menu.

Navigate to the Values tab and change the Angle parameter to 45.
Navigate to the Rules tab.
Change the Premise to B.

Rule 1: A=-FKF+FKF+FKF-
Rule 4: B=FFFFFF++A++FFFFFF++A:.21
Rule 6: B=F++FKFA++AFKFA+K+FFA++FAA:.21

Note that the :.21 on the end of each line for the variable B represents a probability that the rule will be used. This is controlled with the Random Seed parameter.

3) Drop down a Box SOP from the tab menu, and plug the output into the leaf K input of the L-system SOP.

The box is copied every time the variable K is inside of a Rule. We will use this as a cookie cutter for our windows.

4) Append a transform SOP to the L-system SOP, name it "centroid". (You can append a node by right-clicking the output of the node, and the tab menu will appear)

In the Translate x,y, and z parameters, enter in the values: -$CEX, -$CEY, and -$CEZ
This will take the subtract the centroid of the object from its current position, hence, moving the object to its centroid.

5) Append a Delete SOP to the "centroid" node.

Select the lsysK group from the group pull-down arrow to the right of the Group parameter.
Name this Delete SOP "Floor_Outline"
Copy and paste this node, using ctrl+c and ctrl+v, and name the new copy "Windows".
Change the Windows Delete SOP's Operation parameter from "Delete Selected", to "Delete Non-Selected".

6) Append a Facet SOP to the Floor_Outline.

Change the Consolidate parameter to "Consolidate Points Fast".

7) Append an Add SOP to the Facet SOP.

Toggle on "Delete Geometry But Keep the Points".
Navigate to the Polygons tab, and toggle on "By Group", and toggle on "Closed".

8) Append a Copy SOP to the Add SOP. Name this copy_for_skin.

Change the Number of Copies to 2
Change the Translate Z parameter to 0.2

9) Append a Skin SOP to the Copy SOP. Name it "skin_walls".

Toggle on "Keep Primitives".

10) Append a Facet SOP to the skin_walls node. Name it Facet_cusp_polys.

Toggle on "Cusp Polygons".

11) Go back up to the branched off Window Delete SOP and append a Transform SOP. Neme this center_windows

In the Translate Z parameter, put in the expression(This will reference the center of the Z axis of the skin_walls SOP, to align the windows):


12) Append a Cookie SOP to the Facet_cusp_polys node. Name the Cookie SOP Windows_outline

Plug in the center_windows node into the second input of the Cookie.
Change the Operation to "User Defined".
Toggle on "Keep Inside A".
Copy and paste this node, using ctrl+c and ctr+v, and name the new node walls_outline.
Toggle off "Keep Inside A", and Toggle on "Keep Outside A".

13) Drop down a Circle SOP nearby the Windows_outline

Change the Primitive Type to "Polygon".
Change the Radius in both x and y to 0.004
Change the Divisions to 4

14) Append a Sweep SOP to the Circle SOP.

Navigate to the Output tab.
Change the Skin Output parameter to "Skin with Preserve Shape and Auto Closure".
Toggle on "Output Polygons".
Plug in the output of the Windows_outline node to the second input of the Sweep SOP.

15) Append a Facet SOP to the Sweep SOP.

Change the Consolidate parameter to "Consolidate Points Fast".
Toggle on "Cusp Polygons".

16) Append a Merge SOP to the walls_outline node, and connect the last Facet SOP to the input of the Merge SOP.

17) Append a Copy SOP to the Merge SOP, name it Copy_Floors.

Navigate to the copy_for_skin node's Translate Z parameter, hold down the right-click button over the parameter, and select "Copy Parameter".
Navigate to the Copy_Floors node's Translate Z parameter, hold down the right-click button over the paramter, and select "Paste Copied Relative Refs".
You could also type the value in yourself:


18) Select the entire network, and hit shift+c, to collapse everything into a subnet.

You can also ctrl+RMB to select "Collapse into subnet" from the menu.

19) Name the new node, and right-click, and select, "Create Digital Asset".

20) Select a place for you to store the .otl file, and name the Operator Type, and Operator Name.

The Operator Label is used for the tab menu.
The Operator Name is the actual name of the asset, it's type, and default name when first dropped into a network.
Click Accept.

21) Now the Type Properties dialog should appear. Naviagte to the parameters tab.

You can simply drag and drop parameters.
copy_for_skin's tz parameter, name this floor hieght.
box1's sizey, name this window width.
box1's sizez parameters, name this window height.
Copy_Floors's ncy parameter, name this number of floors.
lsystem1's Random Seed parameter, name this floor plan.

22) Click accept, and start modifying the paramters.

floor hieght: 0.3
window width: 1.75
window height: 2
number of floors: 4
floor plan: 1

23) Let's start using expressions in the paramters, to attempt to generate buildings.

floor hieght: rand($F)*.4+.1
window width: fit(rand($F)*2,0,2,.6,2)
window height: ch("Floor_Height")*(rand($F)+3)
number of floors: rint(rand($F)*10)+1
floor plan: rint(rand($F)*10)

(make 3 strings, two with a pulldown, one gets and gives parameters)
- creating menus that are dynamic and read networks within a project
*foreach loops
*run expression
*chs() vs chsraw()

* This dropdown menu will allow us to control any mantra nodes dynamically.
* Create a string parameter, change the name to "node", Label to "Select Node:"
* Go to the Menu tab in Type Properties.
* Toggle on Use Menu, as well as Menu Script.
* Menus require two values, Token and Label.
* Token is the value you would get when using chs().
* Label is what you see when you are navigating through the menu items.

    # Basic menu script to understand using two values:
# One value for Token, and the second value for Label:

echo 1 on
echo 0 off

# Menu script using foreach():

foreach x(`("object light shadow")`)
echo $x $x

* Use expressions like strreplace() on the label to make menus look nicer
* Use the run() expression to return the output of Hscript commands.
* Use the following code in the menu script:

    # Lists all nodes of type "mantra", within the path "/out"

foreach x(`run("opfind -p /out -t mantra")`)
echo $x `strreplace($x,"/out/","")`

* Create a string parameter, change the name to "parameter", Label to "Select Parameter:"
* Go to the Menu tab in Type Properties.
* Toggle on Use Menu, as well as Menu Script.
* Use the following code:

    # Lists all the parameters of the selected node:

set OP = `chs("node")`
foreach z(`run("opparm -l $OP *")`)
echo $z $z

* Create a string parameter, change the name to "value", check off Label.

    # This is used as a callback on the parameter string to "get" the values:
opparm `oppwf()` value ("`chsraw(chs("node") + "/" + chs("parameter"))`")

# This is used as callback on the value string to "give" the values.
opparm `chs("node")` `chs("parameter")` ("`chsraw("value")`")

* The difference between `chs()` and `chsraw()`:

    echo `chs("mantra1/picture")`

echo `chsraw("mantra1/picture")`

* Use source command along with chs() to source a script depending on what you select from pulldown.

    source opdef:.?`chs("button")`


Edit Contents / Running Scripts

* Callbacks - source command
* opdef:Object/HDAname?script
* opdef:.?script
* passing arguments into scripts
* Using scripts to change parameters

    # this defines the table/label of the current otl

set table = `optypeinfo(oppwf(),"T")`
set label = `optype(oppwf())`
set OTL = ${table}/${label}

Create: Curve / Sweep HDA:

* Load MakeCurves.hip file. Jump into Curve_Example Geometry.
* Select all nodes except the two curve SOPs at the very top. ( input_curve & input_profile )
* Shift + C to create a Subnet
* Right Click, and Create Digital Asset.
* Use 2 minimum inputs and 2 for maximum inputs.
* Operator Name is used for the default name for new nodes, and to classify the type of HDA.
* Operator Label is used when adding a node from the tab menu.
* Create a name for otl file, specify a path and click Accept.
* Use naming in the input/output tab of Type Properties to aid artists. ( profile & curve )
* Create two string parameters, profile and curve.
* Change the Curve SOPs coords parameters so they are referencing the newly created parameters:

     /obj/MyHDA/profile_curve/coords:       `chs("../profile")` 
/obj/MyHDA/base_curve/coords: `chs("../curve")`

* These will be hidden parameters in the HDA.

* The following script will make an array out of all the points in a given SOP.
* The null SOPs, which are at the top of the subnet, inherhit the points from the subnet Input.
* It does a for loop on all the points from the source input, using point() to get position data.
* We can put this script in an event script.
* In Type Properties, navigate to the Events tab, and choose OnInputChanged.
* $arg1 is the path to the HDA when using Event Scripts.

set OP = $arg1/curve
set zed=""
for i = 0 to `npoints("$OP")-1`

set zed = $zed `point($OP,$i,P,0)`,`point($OP,$i,P,1)`,`point($OP,$i,P,2)`

opparm $arg1 curve ("$zed")

set OP = $arg1/profile
set zed=""
for i = 0 to `npoints("$OP")-1`

set zed = $zed `point($OP,$i,P,0)`,`point($OP,$i,P,1)`,`point($OP,$i,P,2)`

opparm $arg1 profile ("$zed")

* Create a reload button, with the following callback for recooking when not changing inputs:

    source opdef:.?OnInputChanged `oppwf()`

* Promote switch, resample, and carve controls.
* Hide curve and profile parameters.



* Saving contents to disk.
* Passing arguments to, and running scripts on disk.
* Adding contents to HDAs and saving contents to disk from HDAs.

# this deletes a section named array

otcontentdelete $OTL array
otcontentdelete Object/MyHDA array

# this adds a section named array from $TEMP/$file

otcontentadd $OTL array $TEMP/$file
otcontentadd Object/MyHDA array $TEMP/array.txt

# this does a loop an all the content in an HDA and dumps it to disk.

foreach content(`run("otcontentls $OTL")`)
otcontentsave -o $TEMP/$content $OTL $content

# this would make a file executable and run it, if you dump a shell script.

unix chmod + x $file
unix ./$file

# pass an argument into a script

unix ./$file $arg1

  - hscript
    *source hscript command
    *opdef syntax
  - OnInputChanged, OnLoaded, etc.
  - on event, vs manual trigger
    *$arg1 vs. oppwd()

  - emulating Maya's paint tools.
    *panepath hscript command
    *opset hscript command

      This brings up two cases-
        *unlocked asset
            directly referencing a node inside
            downside is that asset must remain unlocked
       *locked asset
            dropping down a new curve sop
            having a chs() expression within the asset referencing a hidden parameter
            using opparm to change the hidden parameter to reference the new node
// unlinks pane1 and moves play bar (lower case L and a zero are used)
pane -l 0 -p pane1

// without moving playbar
pane -l 0 pane1

// adds new object with a curve and profile
opcd /obj
opadd geo newcurve
opcd newcurve
opadd curve curve1
// navigate to curve then select curve
panepath -p pane1 -f /obj/newcurve/curve1
opset -d on -r on -p on /obj/newcurve/curve1
viewlayout -q Build.*.world

// initialize and go back up
opset -d on -r on -p on /obj/newcurve/end
panepath -p pane1 -f /obj/newcurve
viewlayout -s 2 Build.*.world

  - render automation<
    *unix hscript command<
    *otcontentadd, otcontentsave hscript commands<
    *generating a render script
    *triggering a render through the shell

hcommand -ports in houdini
python socket