From acc96e3fade50fa7c404bf6ee47b1ea085685f16 Mon Sep 17 00:00:00 2001 From: Evan Pratten Date: Mon, 9 Oct 2023 14:06:45 -0400 Subject: [PATCH] Adding Hou & RDP stuff --- .vscode/settings.json | 1 + configs/scripts/houdini-tool.py | 55 +++++++++++++------- helpers/generate-rdp-tls-certs.sh | 11 ++++ python_modules/ewpipe/common/utils/path.py | 11 ++++ python_modules/ewpipe/houdini/editions.py | 14 +++++ python_modules/ewpipe/houdini/environment.py | 37 +++++++++++++ 6 files changed, 109 insertions(+), 20 deletions(-) create mode 100644 helpers/generate-rdp-tls-certs.sh create mode 100644 python_modules/ewpipe/common/utils/path.py create mode 100644 python_modules/ewpipe/houdini/environment.py diff --git a/.vscode/settings.json b/.vscode/settings.json index 270f0cd..4877f66 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,4 +11,5 @@ "python.analysis.extraPaths": [ "./python_modules" ], + "python.formatting.provider": "black", } \ No newline at end of file diff --git a/configs/scripts/houdini-tool.py b/configs/scripts/houdini-tool.py index 4e45e38..436b9ed 100755 --- a/configs/scripts/houdini-tool.py +++ b/configs/scripts/houdini-tool.py @@ -11,14 +11,15 @@ import argparse import subprocess import logging from ewpipe.common.dirs import HOUDINI_PROJECTS_DIR +from ewpipe.common.utils.path import prepend_if_relative from ewpipe.houdini.editions import ( get_binary_name_for_edition, get_houdini_edition_args, HOU_EDITIONS, + noncomercialize_path, ) from ewpipe.houdini.installations import get_houdini_installation_path from ewpipe.common.logging import configure_logging -from ewpipe.common.env import diff_from_current_env logger = logging.getLogger(__name__) @@ -52,6 +53,10 @@ def main() -> int: ap.add_argument( "--no-project-env", help="Disables setting $HIP and $JOB", action="store_true" ) + ap.add_argument("--cpu", help="Use CPU compute for OpenCL", action="store_true") + ap.add_argument( + "--dump-core", help="Forces Houdini to dump its core", action="store_true" + ) ap.add_argument("--verbose", "-v", help="Verbose output", action="store_true") args = ap.parse_args() @@ -66,43 +71,53 @@ def main() -> int: logger.info(f"Selected Houdini {hou_path.name[3:]} from {hou_path}") # Determine the project path - project_path = Path(args.project) - if not project_path.is_absolute(): - # This is a project name, not a path - project_path = HOUDINI_PROJECTS_DIR / project_path + project_path = prepend_if_relative(HOUDINI_PROJECTS_DIR, Path(args.project)) + project_save_file = project_path / f"{project_path.name}.hip" logger.info(f"Opening project from: {project_path}") # If the directory does not exist, create project_path.mkdir(parents=True, exist_ok=True) # If allowed, set up env vars - environment_vars = os.environ.copy() - environment_vars["HOUDINI_SCRIPT_DEBUG"] = "1" - environment_vars["HOUDINI_SPLASH_MESSAGE"] = "Loading with custom scripts" - environment_vars["HOUDINI_CONSOLE_PYTHON_PANEL_ERROR"] = "1" + hou_env_settings = {} + hou_env_settings["HOUDINI_SCRIPT_DEBUG"] = "1" + hou_env_settings["HOUDINI_SPLASH_MESSAGE"] = "Loading with custom scripts" + hou_env_settings["HOUDINI_CONSOLE_PYTHON_PANEL_ERROR"] = "1" + hou_env_settings["HOUDINI_PDG_NODE_DEBUG"] = "3" + if args.cpu: + hou_env_settings["HOUDINI_OCL_DEVICETYPE"] = "CPU" + hou_env_settings["HOUDINI_USE_HFS_OCL"]="1" + if args.dump_core: + hou_env_settings["HOUDINI_COREDUMP"] = "1" if not args.no_project_env: # environment_vars["HIP"] = str(project_path) - environment_vars["JOB"] = str(project_path) - environment_vars["HOUDINI_HIP_DEFAULT_NAME"] = f"{project_path.name}.hip" + hou_env_settings["JOB"] = str(project_path) + hou_env_settings["HOUDINI_HIP_DEFAULT_NAME"] = project_save_file.name # Figure out what has changed in the environment and print the changes - env_changes = diff_from_current_env(environment_vars) - if env_changes: + if hou_env_settings: logger.info("Environment changes:") - for key, value in env_changes.items(): + for key, value in hou_env_settings.items(): logger.info(f" ${key}: {value}") + + # Combine the current environment with + cmd_env = dict(os.environ) + cmd_env.update(hou_env_settings) - # Launch houdini + # Build command to launch houdini cmd = [ str(hou_path / "bin" / get_binary_name_for_edition(args.type)), "-foreground", ] + get_houdini_edition_args(args.type) - if (project_path / f"{project_path.name}.hip").exists(): - cmd.append(f"{project_path}/{project_path.name}.hip") - if (project_path / f"{project_path.name}.hipnc").exists(): - cmd.append(f"{project_path}/{project_path.name}.hipnc") + + # If the expected project file exists already + # (aka, user already saved in a previous session), + # then conveniently open the project automatically + cmd.append(str(noncomercialize_path(project_save_file))) + + # Run houdini logger.info(f"Running: {' '.join(cmd)}") - status = subprocess.run(cmd, env=environment_vars, cwd=project_path).returncode + status = subprocess.run(cmd, env=cmd_env, cwd=project_path).returncode return status diff --git a/helpers/generate-rdp-tls-certs.sh b/helpers/generate-rdp-tls-certs.sh new file mode 100644 index 0000000..3a7a657 --- /dev/null +++ b/helpers/generate-rdp-tls-certs.sh @@ -0,0 +1,11 @@ +#! /bin/sh +set -e + +# Make the keys dir +KEYS_DIR=~/.config/gnome-remote-desktop/keys +mkdir -p $KEYS_DIR + +# Generate keys +openssl genrsa -out $KEYS_DIR/tls.key 4096 +openssl req -new -key $KEYS_DIR/tls.key -out $KEYS_DIR/tls.csr +openssl x509 -req -days 36500 -signkey $KEYS_DIR/tls.key -in $KEYS_DIR/tls.csr -out $KEYS_DIR/tls.crt diff --git a/python_modules/ewpipe/common/utils/path.py b/python_modules/ewpipe/common/utils/path.py new file mode 100644 index 0000000..0ba0a2a --- /dev/null +++ b/python_modules/ewpipe/common/utils/path.py @@ -0,0 +1,11 @@ +from pathlib import Path + + +def prepend_if_relative(prefix: Path, possibly_abs_path: Path) -> Path: + + # If absolute, no prepend needed + if possibly_abs_path.is_absolute(): + return possibly_abs_path + + # Otherwise prepend + return prefix / possibly_abs_path diff --git a/python_modules/ewpipe/houdini/editions.py b/python_modules/ewpipe/houdini/editions.py index af487c8..ee96dc0 100644 --- a/python_modules/ewpipe/houdini/editions.py +++ b/python_modules/ewpipe/houdini/editions.py @@ -1,4 +1,5 @@ from typing import List +from pathlib import Path HOU_EDITIONS = ["core", "fx", "indie", "apprentice"] """All possible Houdini editions.""" @@ -34,3 +35,16 @@ def get_houdini_edition_args(edition: str) -> List[str]: return [f"-{edition}"] else: return [] + + +def noncomercialize_path(input_path: Path) -> Path: + # Figure out the noncomercial version of the path + path_suffix = input_path.suffix + noncomercial_path = input_path.with_suffix(f".{path_suffix}nc") + + # If the NC version exists, use it + if noncomercial_path.exists(): + return noncomercial_path + + # All other cases, use the input directly + return input_path diff --git a/python_modules/ewpipe/houdini/environment.py b/python_modules/ewpipe/houdini/environment.py new file mode 100644 index 0000000..4bceff9 --- /dev/null +++ b/python_modules/ewpipe/houdini/environment.py @@ -0,0 +1,37 @@ +from dataclasses import dataclass, field, fields +from typing import Dict, Optional + + +@dataclass +class HoudiniEnvironment: + script_debug: bool = field(default=True, metadata={"key": "HOUDINI_SCRIPT_DEBUG"}) + """If set, errors will be printed when loading dialog scripts and scripted operators.""" + + show_py_panel_errors_in_console: bool = field( + default=True, metadata={"key": "HOUDINI_CONSOLE_PYTHON_PANEL_ERROR"} + ) + """Errors when starting python panels will also be sent to the console, instead of just displaying them within the panel.""" + + pdg_node_debug_level: int = field( + default=3, metadata={"key": "HOUDINI_PDG_NODE_DEBUG"} + ) + """Determines if PDG should print out node status information during the cook. + + 1: Enable a status print out message each time a node finishes cooking + 2: 1 + node error messages + 3: Print node generation/cook status, errors and node warnings + 4: 3 + print a message for each node callback invocation + """ + + splash_message: Optional[str] = field( + default=None, metadata={"key": "HOUDINI_SPLASH_MESSAGE"} + ) + """Message shown on the splash screen""" + + def to_dict(self) -> Dict[str, str]: + output: Dict[str, str] = {} + for obj_field in fields(self): + field_value = self.__dict__[obj_field.name] + if field_value: + output[obj_field.metadata["key"]] = str() + return output