Skip to content

Commit

Permalink
Houdini 20 Update (#23)
Browse files Browse the repository at this point in the history
Houdini 20 Update

---------

Co-authored-by: Aleksei Rusev <arusev@nvidia.com>
  • Loading branch information
alexxbb and Aleksei Rusev authored Mar 14, 2024
1 parent 550856a commit 722d01a
Show file tree
Hide file tree
Showing 25 changed files with 1,538 additions and 786 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ repository = "https://github.com/alexxbb/hapi-rs/"
keywords = ["vfx", "graphics", "gamedev", "houdini"]
categories = ["graphics", "game-development"]
readme = "README.md"
version = "0.9.3"
version = "0.10.0"
authors = ["Aleksei Rusev <hou.alexx@gmail.com>"]
edition = "2021"
license = "MIT"
Expand All @@ -30,3 +30,4 @@ fastrand = "1.6.0"
anyhow = "1.0.66"
argh = "0.1.9"
ctrlc = "3.2.5"
tinyjson = "2.5.1"
23 changes: 18 additions & 5 deletions bindgen/coverage/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,22 @@ use std::path::Path;
fn raw_hapi_function_names() -> HashSet<Item> {
const IGNORE_SUFFIX: &[&str] = &[
"_IsString",
"_IsNonValue",
"_IsFloat",
"_IsInt",
"_AreEqual",
"_IsPath",
"_IsNode",
"_Create",
"_Init",
"HAPI_CreateCustomSession",
"HAPI_SetCustomString",
"HAPI_RemoveCustomString",
"HAPI_GetHandleInfo",
"HAPI_BindCustomImplementation",
"HAPI_GetImageFilePath",
"HAPI_GetHandleBindingInfo",
"HAPI_GetWorkitemResultInfo"
];
let raw = Path::new("../../src/ffi/bindings.rs");
let text = std::fs::read_to_string(&raw).expect("bindings.rs");
Expand Down Expand Up @@ -53,14 +62,18 @@ fn wrapped_rs_function_names() -> HashSet<Item> {
let rx2 = Regex::new(r#"\[(HAPI\w+)\]"#).unwrap();
let rx3 = Regex::new(r#".*raw::(HAPI\w+)\("#).unwrap();

let text = std::fs::read_to_string("../../src/ffi/functions.rs").expect("functions.rs");
let text = std::fs::read_to_string("../../src/ffi/functions.rs").expect("ffi/functions.rs");
let it1 = rx1.captures_iter(&text).map(|c| Item(c[1].to_string()));

let text = std::fs::read_to_string("../../src/attribute/bindings.rs").expect("functions.rs");
let it2 = rx2.captures_iter(&text).map(|c| Item(c[1].to_string()));
let ffi_functions = it1.chain(it2);

let text =
std::fs::read_to_string("../../src/attribute/bindings.rs").expect("attribute/bindings.rs");
let it1 = rx2.captures_iter(&text).map(|c| Item(c[1].to_string()));
let it2 = rx3.captures_iter(&text).map(|c| Item(c[1].to_string()));
let attribute_bindings = it1.chain(it2);

let it3 = rx3.captures_iter(&text).map(|c| Item(c[1].to_string()));
HashSet::from_iter(it1.chain(it2).chain(it3))
HashSet::from_iter(ffi_functions.chain(attribute_bindings))
}

fn main() {
Expand Down
4 changes: 2 additions & 2 deletions bindgen/hapi-bindgen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl StripMode {

static ENUMS: Lazy<HashMap<&str, (&str, i32)>> = Lazy::new(|| {
// -N translates to StripMode::StripFront(N)
// N translates to StripMode::KeepFront(N)
// N translates to StripMode::KeepTail(N)
let mut map = HashMap::new();
map.insert("HAPI_License", ("auto", -2));
map.insert("HAPI_Result", ("HapiResult", 2));
Expand Down Expand Up @@ -93,7 +93,7 @@ static ENUMS: Lazy<HashMap<&str, (&str, i32)>> = Lazy::new(|| {
map.insert("HAPI_InputType", ("auto", -1));
map.insert("HAPI_GeoType", ("auto", -1));
map.insert("HAPI_AttributeTypeInfo", ("auto", -1));
map.insert("HAPI_StorageType", ("auto", -1));
map.insert("HAPI_StorageType", ("auto", 2));
map.insert("HAPI_VolumeVisualType", ("auto", -1));
map.insert("HAPI_VolumeType", ("auto", -1));
map.insert("HAPI_CurveType", ("auto", -1));
Expand Down
3 changes: 2 additions & 1 deletion env.ps1
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
$env:HFS = "C:\Houdini\19.5.716";
#$env:HFS = "C:\Houdini\19.5.805";
$env:HFS = "C:\Houdini\20.0.636";
$env:PATH += ";${env:HFS}\bin"
6 changes: 3 additions & 3 deletions examples/create_pdg_network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ use std::time::Duration;
fn main() -> anyhow::Result<()> {
const PIPE: &str = "hapi";
// Try to connect toa possibly running session
let session = match connect_to_pipe(PIPE, None, None) {
let session = match connect_to_pipe(PIPE, None, None, None) {
Ok(session) => session,
Err(_) => {
// No session running at PIPE, start the Houdini process.
let hfs = std::env::var_os("HFS").ok_or_else(|| anyhow!("Missing HFS"))?;
let executable = Path::new(&hfs).join("bin").join("houdini");
start_houdini_server(PIPE, executable, false)?;
let child = start_houdini_server(PIPE, executable, false)?;
// While trying to connect, it will print some errors, these can be ignored.
connect_to_pipe(PIPE, None, Some(Duration::from_secs(50)))?
connect_to_pipe(PIPE, None, Some(Duration::from_secs(50)), Some(child.id()))?
}
};

Expand Down
6 changes: 3 additions & 3 deletions examples/live_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ fn main() -> Result<()> {
let args: Args = argh::from_env();
const PIPE: &str = "hapi";
// Try to connect toa possibly running session
let session = match connect_to_pipe(PIPE, None, None) {
let session = match connect_to_pipe(PIPE, None, None, None) {
Ok(session) => session,
Err(_) => {
// No session running at PIPE, start the Houdini process.
// Edit the executable path if necessary.
let hfs = std::env::var_os("HFS").ok_or_else(|| anyhow!("Missing HFS"))?;
let executable = Path::new(&hfs).join("bin").join("houdini");
start_houdini_server(PIPE, executable, true)?;
let child = start_houdini_server(PIPE, executable, true)?;
// While trying to connect, it will print some errors, these can be ignored.
connect_to_pipe(PIPE, None, Some(Duration::from_secs(50)))?
connect_to_pipe(PIPE, None, Some(Duration::from_secs(50)), Some(child.id()))?
}
};

Expand Down
84 changes: 84 additions & 0 deletions hython/dictionary_attribute.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import hapi
import json

session = hapi.createInProcessSession()

cook_options = hapi.CookOptions()
try:
hapi.initialize(session, cook_options)
except hapi.AlreadyInitializedError:
pass


def get_string(handle) -> str:
_len = hapi.getStringBufLength(session, handle)
return hapi.getString(session, handle, _len)


# Create a node
node = hapi.createInputNode(session, "input_node")

part_info = hapi.PartInfo(
vertexCount=0, faceCount=0, pointCount=1, type=hapi.partType.Mesh
)

hapi.setPartInfo(session, node, 0, part_info)

# Positions
p_info = hapi.AttributeInfo(
exists=True,
owner=hapi.attributeOwner.Point,
count=1,
tupleSize=3,
storage=hapi.storageType.Float,
originalOwner=hapi.attributeOwner.Invalid,
)

hapi.addAttribute(session, node, 0, "P", p_info)
hapi.setAttributeFloatData(session, node, 0, "P", p_info, [0.0, 0.0, 0.0], 0, 1)

# Create Dictionary Attribute
attr_info = hapi.AttributeInfo(
exists=True,
owner=hapi.attributeOwner.Detail,
count=1,
tupleSize=1,
storage=hapi.storageType.Dictionary,
originalOwner=hapi.attributeOwner.Detail,
totalArrayElements=0, # THIS MUST BE 0 FOR THIS EXAMPLE
)

# Uncomment to see getAttributeDictionaryData fail with error (Houdini 20.0.625):
# "hapi.InvalidArgumentError: Invalid argument given: Data array length must match AttributeInfo.totalArrayElements."
# ================================
# attr_info.totalArrayElements = 1
# ================================

# Uncomment to see Hython segmentation fault
# =========================
# attr_info.tupleSize = 7
# =========================

DICT_ATTR = "my_dict_attr"

hapi.addAttribute(session, node, 0, DICT_ATTR, attr_info)

in_data = {"foo": 7}

hapi.setAttributeDictionaryData(
session,
node,
0,
DICT_ATTR,
attr_info,
[json.dumps(in_data)], # data
0, # start
1, # sizes length
)

hapi.commitGeo(session, node)
hapi.cookNode(session, node, hapi.CookOptions())

handles = hapi.getAttributeDictionaryData(session, node, 0, DICT_ATTR, attr_info, 0, 1)
out_json = get_string(handles[0])
assert in_data == json.loads(out_json)
Binary file modified otls/hapi_geo.hda
Binary file not shown.
12 changes: 11 additions & 1 deletion src/attribute/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ where
}
}

/// Represents multi-array string data. Returned by [`crate::attribute::StringArrayAttr::get`]
/// Represents multi-array string data. Used as storage for string and dictionary array attributes.
/// Each element of this array is itself a [`StringArray`]
pub struct StringMultiArray {
pub(crate) handles: Vec<StringHandle>,
pub(crate) sizes: Vec<i32>,
Expand Down Expand Up @@ -140,6 +141,15 @@ impl StringMultiArray {
cursor: 0,
}
}
/// Convenient method to flatten the multi-dimensional array into a single vector.
pub fn flatten(self) -> Result<(Vec<String>, Vec<usize>)> {
let mut flat_array = Vec::with_capacity(self.sizes.iter().sum::<i32>() as usize);
let mut iter = self.iter();
while let Some(Ok(string_array)) = iter.next() {
flat_array.extend(string_array.into_iter());
}
Ok((flat_array, self.sizes.iter().map(|v| *v as usize).collect()))
}
}

impl<'a> Iterator for MultiArrayIter<'a> {
Expand Down
Loading

0 comments on commit 722d01a

Please sign in to comment.