_Preface_ Brief release notes are listed in reverse chronological order. Each build ID is a concatenation of a timestamp and a content specification. The 'iron' specification merely indicates that the specialized chain, grass, and tree tools are included in addition to the core set of surface operators. *20171017_iron* Lua node graph evaluation has been further developed. Perlin and white noise has been made available through FastNoise. Preliminary OpenCL support has been added. Several grass/fur grooming operators have been added in both OpenCL and non-OpenCL forms. SurfaceWrapOp now allows for multiple copies of the reference driver geometry in the deformed driver geometry, result in multiple wrapped instances of the input geometry in the output geometry. *20170811_iron* Houdini redo mechanics has been fixed. CurveSampleOp has been added for working with CVs on curves. The initial implementation allows for redistribution of CVs based on a density plot. HammerOp has been rebuilt without the multi-mod concept. Instead, it will follow the cooperative node concept similar to WayPointOp. High DPI support has been added, adjusting some visual elements when very small pixels are detected. Preliminary Houdini Engine support has been added. Houdini hip files can be loaded as though they are geometry files, such as with ImportOp. Operator support has been added to Lua. This allows operator graphs, such as seen in Houdini, to be written in Lua code instead. The vegetation simulator now supports multiple roots, such for shrubs or when parenting to a modeled trunk. The TreeOp now supports a wind velocity attribute to allow arbitrary vector fields, such as from a fluid simulation. There are also additional controls for impact Reactivity and Threshold. LimberOp has been added to infer a tree structure from somewhat arbitrary sets of curves. The input should be tree-like, but does not need to have perfect intersections at branching points. The choice of where to connect branches versus starting new roots is done by relative position and direction of the candidate segments. Hydra usage has been updated for better performance. All nodes of a model are now put into a single delegate (instead of one delegate per node) and more care is taken when marking objects dirty. A USD file loader has been added, initially supporting meshes, curves, and points. The search tree generation algorithm has been multi-threaded and optimised (using a quick select instead of quick sort). The change can be quite noticable when first picking on a complex model in the viewer. *20170206_iron* USD/Hydra support has been expanded to include dynamic lighting and self-shadowing. Alpha channel support has been cleaned up for all supported primitives (meshes, curves, and points). *20170109_iron* Rudimentary support for USD/Hydra has been added. Additional viewer options have been added including color modes, showing normals, and changing multi-sampling. The viewer can also recognize and draw Alembic instances as the same buffer. *20161201_iron* The viewer now has a slash menu. Camera support has been added as well orthogonal and UV modes. OpenVDB support has been updated. The openvdb path can now be set to auto which looks for support in Houdini 14+ installs. *20161025_iron* The OpenGL driver now supports Vertex Buffer Objects for caching geometry data on the GPU. SurfaceBindOp has a new parameter "Samples" that will lay down a given number of attachments along the length of each fragment. Each input point in the fragment will bind to a smooth line through the attachments. SurfaceWrapOp can contract points in this tubular space towards the root, if necessary, to compensate for stretching. This can be used to attach feathers or scales, potentially avoiding the excessive deformations that can occur in a simple point wrap. LengthCorrectOp has new parameters including Restoration, Restraint, Orientation Bias, Unfolding, and Refolding. The usefulness of these options is still being determined. The original XGen libraries from AutoDesk are now automatically copied and altered to remove the unnecessary dependencies that can cause TLS failures. Also, the ineffective XGen multi-threading is now forceably turned off to avoid evident memory corruption. SurfaceViewerOp now has controls for contrast, brightness, pick scanning, and spiral mode. Some file drivers now provide an outline, shown on screen, and the viewer will automatically scroll the outline to each selected part. *20160816_iron* SurfaceViewerOp now supports the meta key (alt), hiding, isolation, and ghosting. FollicleOp now supports input primitives, using fragmentation. An internal proxy point is automatically created for each fragment. The proxy points operate just as in the original point mode. On output, the fragments are wrapped to their proxy points, accounting for rotation from the driver surface, if available. TubeOp has been added which convert curves with a radius attribute into surfaces with a circular cross-section. *20160615_iron* The QuickViewerOp has been improved with many picking and inspection features. RecordOp has been renamed to NetworkOp with support for launching its own server. Alembic color and part support has been added. Python surfacing editing has been prototyped. *20160418_iron* Filmbox (.fbx) joint import support has been added. Further testing will probably be needed before it is ready for production work. Alembic support now imports curves. XGen support now includes individual curve colors. Houdini point support has been inproved which allows SurfaceBindOp to use point clouds as driver surfaces (requires tangent and normal attributes). *20160328_iron* The Alembic driver can now import meshes (in addition to joint hierarchies). Abc frame handling has been improved and the intended FPS can often be determined automatically. XGen support has been improved, including the ability to render the curves at arbitrary resolution versus just baking curves in Maya. BenderOp and HingeOp now support transient updates for faster interaction while still following up with a refined solution. BenderOp now allows fragmentation so that many primitives can be treated as a single bendable entity. HingeOp drivers can now be partitioned. Fragment interactions can now be restricted based on which partition they are closest to. HingeOp now accepts a reference frame for consistant pivots. MirrorOp is now multi-threaded. *20160119_iron* The FollicleOp can now highlight parts in a stashed mesh. It stores a part name on it output and then looks for matching parts in the stash. The idea is that the geometry grown from the follicles can be used during the picking process where they are positioned. A StashOp has been added to store a mesh copy global under a key. HingeOp now has a loft adjustment applied at the beginning of the iterations. Balanced response to bidirectional collisions will need more attention. *20160113_iron* MirrorOp was added to duplicate points along an axis. Primitive support may be added later. SurfaceProxyOp was added to generate simplified geometry. The initial options are limited, so currently only a specific oval shape can be produced. HingeOp now has a 'Cross Driver Normal' mode to automatically compute pivot axes. Fragmented input can now use multi-threaded collision detection. *20160104_iron* Geodesic support has been added. A new InfluenceOp has been created that applies values from point samples with geodesic falloff. The FollicleOp interactive interface has been refined. Driver partitioning and undo support has been added. *20151201_iron* Notice, substantial changes have been made in this release, particularly with the Maya meta node now changed to an official deformer. This release may be risky for production work. Mindful testing would be prudent. Assorted compiler warnings were addressed. HammerOp was demoted to oplab for potential redevelopment. FollicleOp has been sent back to alpha to be built up into a production ready tool. Improvements are in progress. A Basis Spline choice has been added to CurveCreateOp. A convergence option can coerce the approximating basis spline into intersecting the input points. The FE Maya interface now utilizes the MPxDeformerNode class instead of the more general MPxNode. This allows for participation in more features of the Maya interface. Connections following the prior method are still supported. HingeOp now allows for multiple fragments with inter-collisions. A new pivot method has been added that allow the axis to be discerned from du on the driver surface. Additional choices may follow. Exploratory Arnold support has been added. General operators are made available as Arnold procedurals. A general pixel shader abstraction is being explored (color, displacment, etc). OpenSubdiv support has been added. It is currently being tested in a simple OpenSubdivOp node. Intel compiler support has been updated. *20150804_iron* The specification has been changed from 'grass' to 'iron' based on new inclusions. A new 'ironworks' module has been added, providing tools for building rigid link chains. These tools are based on the topics to be discussed in the Siggraph 2015 Talk entitled 'Rigid Link Chains in "Kung Fu Panda 3"'. No endorsements should be inferred. DodgeOp now allows a unique partition regular expression for each curve. XGen support has been added, starting with the import of baked curves. Maya is now supported up through 2016. The metadata API has replaced the previous method of storing mesh-rate attributes, starting with 2014. The code has been updated and tested up through gcc 4.9, the current default compiler for Debian Jessie. A separate PuppetOp shift control has been added, distinct from the previously combined stretch control. The stretch control now only acts on the remaining aspect. *20150601_grass* The Houdini 'timeDep' flag has been turned off for all nodes where it was not clearly needed. This removes the compulsion to add a TimeShift node after every SurfaceBindOp. A SurfaceAccessibleLua handler has been added that treats Lua scripts as surfaces. When used with the context input of the ImportOp, this provides capabilites similar to a Houdini attribute wrangle node. Without a context, a new surface will simply be generated. ImportOp now accepts an explicit string input that is treated just like text from a file. This can be useful for writing short Lua scripts. A SurfaceViewerOp has been added with the intent of giving terminal applications a way to show results visually. The viewer runs asynchronously, so the interface can be fully interactive even if the underlying node evaluation updates very infrequently. Quadratic Bezier interpolation has been added to CurveCreateOp. This has been implemented with a MatrixBezier class that resembles MatrixPower, but which only works reliably under limited conditions (presumes the tangent along the local X axis and expects powers from 0 to 1). The Bezier approach can be much faster than the true power function. *20150504_grass* The geo conversion support was cleaned up. The geo export was only working under very limited circumstances. Curve support was added to terminal mode (such as command line python scripts). Instead of having the Maya module create a comprehensive menu based on a presumption of the modules it will load, each module can now add its own section to the Maya FE menu. For Maya, a MeshSeparateOp node was added that divides up a single mesh into a group of meshes based on a string attribute. Generalized Houdini undo functionality was added. This was tested with the BenderOp node. The HobbleOp node can now output a joint. This can be read by several other HobbleOp nodes in order to coordinate adjustments of several independent surfaces. When using Maya or Houdini, the text sent to the shell is now prefixed with "fe ". CacheOp has been improved for less false negatives and less false positives. For Houdini, search trees are now shared where possible. This means that if many nodes use the same driver input, that data only needs to be processed into a searchable structure when the first node accesses it. *20150322_grass* A CacheOp has been added, currently only for Houdini. The cache can be automatically cleared when a parameter change is detected in any upstream node. Further testing will be needed before general production use would be advised. The Houdini 'descriptive name' feature is now supported as a "summary" entry in each operator's attribute catalog. Many operators have added a brief summary for quick feedback in the network view. Preliminary support for Houdini 14 has been implemented. Known OpenGL problems have been resolved. Issues with TBB versioning are still evident. The HobbleOp can now accept a named joint from an added third input surface. Each joint is specified as a primitive with a 'name' string and vector attributes of 'ref[XYZTS]' and 'anim[XYZTS]'. The X, Y, Z, and T vectors are the components of a transform matrix. The 'S' is optional scaling. The points and shape of each joint primitive is ignored, so the visual presentation of joints can be whatever intutive form is desired. A Ptex module has been added. The Ptex handler can be automatically used in the ImportOp for any filename ending in '.ptx'. Currently, a Ptex file is imported as a point cloud with as much as one point per texel. A 'resolution' option can reduce that count. If the ptex file does not contain the context mesh as metadata, the ImportOp now supports an input surface to be used as a context. The ImportOp context can useful as an alternative to the metadata since that mesh can be deformed before positioning the world-space points based on the face-local texels. Maya textures can now be used as attributes. For operator parameters that specify an attribute name, like the "Weight Attribute" on the BloatOp, you can specify the output of a dynamic texture, like "water.outAlpha". Since a period is normally not permitted in an attribute name, its presence triggers this alternate functionality. If a single value texture output, like alpha, is used for a vector attribute, it is treated as a grey color with matching red, green, and blue. If a color output is used for a non-vector attribute, only the first (red) value is used. *20150205_grass* CurveCreateOp now supports input attributes specifying minimim and maximum curve lengths for each section of the curve. This can be used to push or pull vertices away from a pure linear path in order to meet some target distance. DodgeOp now allows for partitioned colliders. In an manner similar to driver partitioning in SurfaceBindOp, primitive subsets can be tagged by name and the repulsion and/or collision responses can be selective. PuppetOp will avoid Euler decomposition for angle scaling when the bending scale for the three axes are equal and the angles are not constrained. This may get more attention as real use cases are further explored. LengthCorrectOp now supports an adjustable temporal effect. With a low response factor, the previous position and velocity will dominate the result. For now, the OpenVDB build script has been tweaked to avoid the new version included with Houdini 14. A multi-version build for the vdb module will be set up later. *20150112_grass* Support for Maya mesh arrays has been implemented by iterating with regular non-array meshes. By using the same signaling approach, but now with the option for multiple iterations against each handler, the impact on existing operators and Houdini support is minimal. Mesh iteration has been used to allow multiple maya meshes to share a single bind and wrap. The surface bind mel script has been updated to use an array wrap for multiple inputs (instead of a unite and separate). Maya interruption support was added. SurfaceBindOp now stores a peak distance per element when using multiple bindings. This data was previously implied by the furthest binding sample (which always ended up with zero weight). The peak distance that is now stored is actually the distance to an extra unstored binding which has no weight, but balances the weights of the selected number of bindings, all of which can now contribute. HingeOp is now multi-threaded and has a temporal option. *20141216_grass* Searchable surfaces now precompute tangents if UVs exist. This should speed up transform sampling, such as for SurfaceWrapOp. Profiling was adjusted to remove a slight overhead that remained even in optimize builds. SurfaceWrapOp now caches driver samples in some cases. *20141124_grass* ImportOp now has an Options parameter of free form string arguments. A 'line' option has been added to request lines between joints instead of transform triangles. The operators in the joint pipeline have been changed to ignore the actual point data in joint calculations, like PuppetOp blending. Only primitive attributes are used except for the color of the first point in each primitive, which is used for preview. The points are still transformed so the can be used for binding. PuppetOp has additional drawing options. An interruption query was added for operators to check if they should stop prematurely. Interrupt support was added for Houdini (hitting the ESC key). The interrupt check was added to several operators. *20141105_grass* GroupOp is now multi-threaded. Also, the bounds and selection set can be visualized. Versions of TBB module now check the compiled header version against the current runtime dso version and will block any modules with newer headers. Also, a multi-threading issue was addressed that could cause a few elements to be passed over during TBB job splitting. Loading of mutex support is now deferred until thread support is requested. A chosen mutex library is now the first choice when checking for thread support. This distinction is currently relevant with TBB support modules since FE puts TBB mutex and thread support in the same library. HingeOp now permits a threshold distance from the collider. It has a new softness setting that allows for a deformation falloff around contact points. LengthCorrectOp now has a collision mode for rooted curves distinct from a general 'whole primitive' mode. *20140929_grass* A Blend option has been added to the Power mode of CurveCreateOp. The Bisect option is now presented as a separate toggle. Alembic modules are now created from any static Alembic libs found in Maya installs. Brush operations can now be selective whether to update the node output. A HingeOp has been added to rotate a rigid surface away from a collider and relative to a driver. The compile variable FE_USE_SSE in the configuration script SET_ENV can now be set to 'auto', which will activate the compiler option to use whatever instruction sets are available on the build machine. A specific numerical value is still permitted, such as the conservative default of '3'. Most current machines can use '4.1' or '4.2'. *20140814_grass* Build verbosity has been trimmed down. CurveCreateOp now accepts an input surface as a path to follow. In addition to simple Cardinal Spline interpolation, a Power Bisect method is introduced that maintains smooth intersecting interpolation through the input points even with wide variations in spacing. Whole curve collision in LengthCorrectOp has been improved. RulerOp has been added to add local grids and interactively measure objects. Houdini brush behavior has been improved. Houdini group support now allows for compound group specs with regex patterns. GroupOp can now combine input groups. *20140626_grass* RasterOp can now load images into point maps. Relative filenames in Maya now evaluate using the project path. LengthCorrectOp now allows for collisions against approximated whole curves instead of only by each point. Currently, this approximation is a shifting hemisphere touching the curve tip and aligned to the normal of each the input surface point. SubdivideOp now has an expansion option to counter some of the inward shrinkage away from the original hull points. This can be used to get a more circumscribed result instead of a somewhat inscribed result. *20140519_grass* The PRCE workaround for broken binaries in the early RHEL6 release has been turned off. ImportOp clears the frame cache when filter or spec value is changed. DodgeOp now allows for adjustment of the influence from nearby skin on the direction of changes. *20140513_grass* An new autoload feature has been added and several of the modules have been changed to only load when needed, specifically alembic, graphviz, image, json, network, oiio, opengl, openil, ray, tiff, vdb, and xml. Many of these modules add support for optional file formats. The threading, mutexing, and regex subsystems already did autoloading, but those all use their own specialized mechanisms. The Maya FE menu now displays a version in the Help menu based on the plugin's file path instead of the build date. DodgeOp now has adjustable skin avoidance. Also, if a skin is provided, it may be used to better align response directions. LengthCorrectOp now has collision spread to spatially smooth the impact of colliders. SurfaceBindOp now has a Metric selector that allows for either the prior behavior of binding by Spatial Distance or a new method of UV Match. SubdivideOp now allows you to turn off the UV bridging and wrap-around features. These features have also been improved. ImportOp can optionally cache the input files as it loads them. RasterOp can optionally make the directory required for the save file. *20140303_grass* JointSeparateOp will not longer eliminate the current output if it receives empty input. Also, it will no longer discard any output joints for which it detects skin bindings (checking for a lockInfluenceWeights plug). MEL for joints allow for sharing of pose and anim importers. *20140210_grass* The PuppetOp now differentiates stretch and bend scaling. MEL for joint setups has been refined. *20140114_grass* Maya menu items have been added for Joint Import and Joint Puppet. The Maya FE brush tool now tries to find a brush-ready ancestral FE operator if a shape or transform is selected. *20131229_grass* PuppetOp has been further developed and now accepts a Pose input as an alternative goal instead of just using the integrated reference skeleton. Visual feedback of joint damping and constraints has been added. Alembic support has been added. Currently, this is only being tested on a preliminary joint format. A JointCombineOp has been added to convert a hierarchy of native Maya joints to a single combined joint surface. OpenImageIO support has been added. The format support is similar to OpenIL with a few more "movie studio" file types. *20131111_grass* ImportOp, PuppetOp, and JointSeparateOp have been added to allow loading of a hierarchical transform structure in Maya joints. Format support and parameter layout of these nodes is still very preliminary. XML support has been added using pugixml. SubdivideOp has been further optimized. *20131021_grass* OpenMP support has been added. SubdivideOp has been optimized. Each Houdini version can use a specific compiler while still using the shared build of the operators. Using operators with a different compiler from the Houdini build may disallow Boost threading, but TBB or OpenMP appear to work fine. Boost and TBB versions for Houdini are automatically detected and are no longer manually listed into the local.py file. The new mixed compiler support also detects the required compiler based on the name boost thread shared object file. QuiltOp has been added to create duplicate backfacing facets. The purpose is to create bloatable colliders from simple single-ply surfaces, but it also can make fluffy pillows fom simple grids. Custom Maya attribute templates have been added for SurfaceBindOp and SurfaceWrapOp. This allows for collapsible sublayouts and bypassing automatic compaction of UI elements. *20130930_grass* Prototype option boxes for FE operators have been added to the Maya menu. These are not approved for production use. A SubdivideOp has been added that applies Catmull-Clark subdivision. An option has been added in SurfaceBindOp to subdivide driver surfaces. This effect can be moderated in the SurfaceWrapOp with Edgy options. In some situations, Maya sets can be recognized as groups. Preliminary support for Thread Building Blocks has been added as an alternative to Boost Threads. *20130903_grass* A ClaspOp has been added that updates ties between pairs of grommets. The result resembles a wrap, but can maintain a taut appearance while also adjusting for collisions. SurfaceBindOp (and SurfaceWrapOp) now have the ability to save fragment locator data in a form needed for the new ClaspOp to attach string ties to wrapped grommets (buttons). The MEL scripts have been cleaned up, particularly when not in the 'Reveal Stages' mode. Also the wrap script should no longer strip out the driver attribute data required to allow partitioned wraps. *20130822_grass* PartitionOp has an option to divide a surface based on which shaders are attached, providing a simple and visual way to group faces in Maya. Currently, this mode is not supported in Houdini. *20130819_grass* A SurfaceMetricOp has been added that generates a point map based on a metric, currently a signed distance function between two inputs. A RasterOp has been added that saves a point map to an image file. A PartitionOp has been added that sets a point string attribute that is unique to each patch of connected primitives. SurfaceWrapOp now has spread option that does spontaneous multi-weighting based on surface connectivity, starting with the barycentric coordinates of the primary contact as the seed weights. SurfaceWrapOp multi-binding weighting now auto-calibrates to give zero weight to the least contributor in order to more smoothly transition with low binding counts. DodgeOp has been rebuilt to use ray casting in addition to nearest point calculations in order to address "knife edge" collisions. *20130723_grass* DodgeOp now has a Dead Zone parameter to prevent effect on a certain number of points at the base of each curve. DodgeOp is undergoing a major rework for better collisions. It is dropping back to beta status. Reading UVs for driver surfaces is Maya has been fixed. If the UVs didn't match the point index, the wrong values were accessed. Maya now shows the real labels instead of the parameter names. New prototypes RecordOp and SpreadsheetOp have been added. RecordOp can save and load surfaces as record group files. Since surfaces can now convert to and from generic Record data, this should eventually allow inter-process exchange of surfaces without disk access. SpreadsheetOp displays surface attribute data, currently just as command line output. This is the start of a Maya spreadsheet to parallel the native one in Houdini. Brush signals are no longer sent to bypassed Houdini nodes. Spatial vectors are now updated properly as output parameters in Maya. The failure was apparent in the conversion results of the HobbleOp node. *20130619_grass* A toggle has been added to the Maya FE menu called 'Reveal Stages'. Activating this option uses the prior behavior. The default new behavior is that the group of the primary input becomes the output of an added operator. In reality, the apparent group is a new parent group that took the old name while the original group is put under the new group, renamed, and hidden. SurfaceNormalOp can now accept custom attribute names and also has a 'Follow Bend' mode that can generate normals for curves without a driver surface when a dominant bend can be determined. A new SurfaceAttrCopyOp has been added. Space delimited lists of point and primitive attributes on a source surface can be copied, by index, to the input surface. The attributes can be renamed while copied with a simple syntax of 'target_name=source_name'. Maya multi-curve meshes are now supported as driver surfaces, such as for wraps. Setting of maya normals has been made much faster. *20130603_grass* The OpenVDB build integration has been cleaned up. Using a blank openvdb include path should now truly dismiss OpenVDB support. The OpenVDB configuration in local.py now has two variables, forge.openvdb_include and forge.openvdb_lib, potentially the same path. Using OpenVDB with Free Electron is still considered preliminary, A new operator OffsetOp has been added. It takes three inputs. The displacement from the second input to the third input is applied to the first input. The offsets are relative to the local space of those first and second inputs, using the normals and a tangent derived from UV values on the first input. The DodgeOp has a new optional third input for a skin surface. This acts in addition to the collider surface, but it is applied after that collider and does not produce repulsion. *20130528_grass* The Maya mel scripting has been generalized and many of the operators can now be added easily through simple menu items. Some operators will still have a unique script, such as the surface wrap. Most of the mel scripting is now exposed in the script subdirectory of the maya build so that their contents can be examined and potentially customized. Maya-specific operators called CurveCombineOp and CurveSeparateOp have been added that allow conversion of Maya native curve objects to and from aggregate open-poly multi-curve meshes. New menu items simplify making the connections. These open-poly meshes are best viewed in wireframe. Icons for Maya are now supplied. See RUN_MAYA for an example of using XBMLANGPATH to present these icons to Maya. The icons would be used when an FE menu item is dragged to a shelf. OpenVDB voxel data can now be used through the uneditable surface interface. Currently this is accessible using Houdini 12.5 for nearest point and bounding calculations, such as DodgeOp and GroupOp. Support and testing is still very preliminary. There is a new entry in local.py used to point to an openvdb build. Current Houdini 12.5 does not provide an openvdb.h associated with their included openvdb library, so openvdb must downloaded and built manually. This will reportedly be unnecessary in the future when SideFX and OpenVDB finalize some details concerning the current API. Note that forge.boost_sources in local.py now has four fields per entry. Any custom local.py will need to be updated, for this and for the OpenVDB variable. *20130513_grass* SurfaceNormalOp now allows four inputs. Reference versions of the first two inputs can be used to stabilize normals on curves generated using a driver surface. SurfaceNormalOp in Ortho mode now uses a tangent based on the prior and next CV instead of the current and next CV, except endpoints which still just use the single adjacent segment. This produces more symmetrical distributions and should help get better wrap results with curve drivers. SurfaceWrapOp now supports point-normal and spline mode for driver curves in addition to the basic linear mode. SpineFitOp now supports partitioning. If used, each partition results in one spine. This allows for common poly input instead of being limited to single-primitive mesh surfaces.