hapi_rs/lib.rs
1#![doc(html_logo_url = "https://media.sidefx.com/uploads/products/engine/engine_orange.svg")]
2//! # Rust bindings to Houdini Engine C API.
3//!
4//! Official HAPI [documentation](https://www.sidefx.com/docs/hengine/):
5//!
6//! Check out the [examples](https://github.com/alexxbb/hapi-rs/tree/main/examples):
7//!
8//! `cargo run --example ...`
9//!
10//!
11//! # Building and running
12//!
13//! **HFS** environment variable must be set for the build script to link to Houdini libraries.
14//!
15//! For runtime discovery of Houdini libraries there are several options:
16//!
17//! ## Mac & Linux
18//!
19//! **Option 1**
20//!
21//! Build with RPATH via the RUSTFLAGS variable:
22//! ```bash
23//! RUSTFLAGS="-C link-args=-Wl,-rpath,/path/to/hfs/dsolib" cargo build
24//! ```
25//! **Option 2**
26//!
27//! Add a cargo config file to your project: `.cargo/config`
28//!```text
29//! [target.'cfg(target_os = "linux")']
30//! rustflags = ["-C", "link-arg=-Wl,-rpath=/opt/hfs/20.5.445/dsolib"]
31//! [target.x86_64-apple-darwin]
32//! rustflags = ["-C",
33//! "link-arg=-Wl,-rpath,/Applications/Houdini/Current/Frameworks/Houdini.framework/Versions/Current/Libraries",
34//! ]
35//!```
36//! **Option 3**
37//!
38//! At runtime via env variables: `$LD_LIBRARY_PATH` on Linux and `$DYLD_LIBRARY_PATH` on MacOS
39//!
40//! ## Windows
41//! `$HFS` variable must be set for building.
42//! Runtime Houdini libraries are required to be in $PATH: Add $HFS/bin to $PATH.
43//!
44//! # API Overview
45//!
46//! This crates aims to be easy to use, hiding the inconvenient C API as much as possible
47//! while also trying to keep function names clear and close to original.
48//! To archive this, the crate wraps every single C struct in a new struct and provide getters/setters for its fields.
49//! All structs and enums have their `HAPI_` prefix removed.
50//!
51//! In addition all enum variants are shortened.
52//! For example:
53//! ```ignore
54//! // Original struct:
55//! struct HAPI_NodeInfo {
56//! pub parmCount: ::std::os::raw::c_int,
57//! ...
58//! }
59//! // This crate's struct:
60//! let info: crate::node::NodeInfo;
61//! let count: i32 = info.parm_count();
62//!
63//! // Original enum (C)
64//! enum HAPI_InputType {
65//! HAPI_INPUT_INVALID = -1,
66//! ...
67//! };
68//! // This crate's enum
69//! enum InputType {
70//! Invalid = -1,
71//! ...
72//! }
73//! ```
74//! Some underlying C structs don't provide a direct way of creating them or they might not provide methods
75//! for modifying them, due to this crate's attempt for proper data encapsulation, minimizing noise and improving safety.
76//! Structs that you **do** need the ability to create, implement [Default] and some a `Builder Pattern` with convenient `with_` and `set_` methods:
77//! ```ignore
78//! let part_info = PartInfo::default()
79//! .with_part_type(PartType::Mesh)
80//! .with_face_count(6);
81//! ```
82//!
83//! # Error type
84//! All API calls return [`HapiError`] ([HAPI_Result](https://www.sidefx.com/docs/hengine/_h_a_p_i___common_8h.html#ac52e921ba2c7fc21a0f245678f76c836))
85//! In case of error, the HapiError struct contains an `Option<String>` with an error message returned from the Engine.
86//! Additional error context is available in the `contexts` field of the error type.
87//!
88//!
89//! # Strings
90//! Houdini Engine being C API, makes life a little harder for Rust programmer when it comes to strings.
91//! The crate chose to accept some overhead related to string conversion in exchange for a nicer API and
92//! easy of use.
93//!
94//! For example getting/setting a parameter value will perform a conversion CString <-> String,
95//! but not in every situation such conversion is acceptable, for example reading geometry string attributes
96//! can be very expensive since we have do potentially thousands of CString to String conversions.
97//!
98//! To aid this situation, the crate provides custom structs which implement different iterators,
99//! which yield CString or String types. See the [`stringhandle`] module for more info.
100//!
101//!
102//! # Nodes
103//! [`node::NodeHandle`] is lightweight handle to a Houdini node, it's returned by some APIs and can not
104//! be created by the users. The [`node::NodeHandle`] has a limited functionality because it doesn't hold
105//! a pointer to the [`session::Session`].
106//!
107//! [`node::HoudiniNode`] is the main type which combines [`node::NodeHandle`], [`node::NodeInfo`]
108//! and [`session::Session`] types into a single struct which exports most of the node APIs.
109//!
110//! Some APIs choose to return a lightweight [`node::NodeHandle`] that can be simply passed to other APIs.
111//! You can upgrade the handle to a full node by [`node::NodeHandle::to_node`] to get access to full node API.
112//!
113//! Due to HAPI only exposes a limited subset of APIs to Houdini, and to keep things simple,
114//! there no different flavors of [`node::HoudiniNode`].
115//! Instead this type provides the common node APIs and some node-type-specific APIs are available
116//! in separate types like [`pdg::TopNode`] and [`geometry::Geometry`] which hold [`node::HoudiniNode`]
117//! as a struct field (composition vs inheritance).
118//!
119//! # Parameters
120//! Parameters are modelled with [`parameter::Parameter`] enum that contains different parameter types.
121//! Common parameter methods are provided in [`parameter::ParmBaseTrait`].
122
123pub mod asset;
124pub mod attribute;
125pub mod geometry;
126pub mod material;
127pub mod node;
128pub mod parameter;
129pub mod session;
130pub mod stringhandle;
131pub mod volume;
132pub mod pdg;
133mod errors;
134mod utils;
135mod ffi;
136
137pub use errors::{HapiError, Result};
138pub use ffi::enums;
139pub use ffi::raw;
140pub use ffi::structs::Viewport;
141
142/// Houdini version this library was build upon
143#[derive(Debug)]
144pub struct HoudiniVersion {
145 pub major: u32,
146 pub minor: u32,
147 pub build: u32,
148 pub patch: u32,
149}
150
151/// Engine version this library was build upon
152#[derive(Debug)]
153pub struct EngineVersion {
154 pub major: u32,
155 pub minor: u32,
156 pub api: u32,
157}
158
159/// Houdini version this library was build upon
160pub const HOUDINI_VERSION: HoudiniVersion = HoudiniVersion {
161 major: raw::HAPI_VERSION_HOUDINI_MAJOR,
162 minor: raw::HAPI_VERSION_HOUDINI_MINOR,
163 build: raw::HAPI_VERSION_HOUDINI_BUILD,
164 patch: raw::HAPI_VERSION_HOUDINI_PATCH,
165};
166
167/// Engine version this library was build upon
168pub const ENGINE_VERSION: EngineVersion = EngineVersion {
169 major: raw::HAPI_VERSION_HOUDINI_ENGINE_MAJOR,
170 minor: raw::HAPI_VERSION_HOUDINI_ENGINE_MINOR,
171 api: raw::HAPI_VERSION_HOUDINI_ENGINE_API,
172};