Skip to content

Commit

Permalink
[Automated] Merged develop into main
Browse files Browse the repository at this point in the history
  • Loading branch information
ynbot committed Oct 7, 2023
2 parents 02b64a4 + d41ac2a commit 958352e
Show file tree
Hide file tree
Showing 49 changed files with 716 additions and 224 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ body:
label: Version
description: What version are you running? Look to OpenPype Tray
options:
- 3.17.2-nightly.2
- 3.17.2-nightly.1
- 3.17.1
- 3.17.1-nightly.3
Expand Down Expand Up @@ -134,7 +135,6 @@ body:
- 3.14.10-nightly.9
- 3.14.10-nightly.8
- 3.14.10-nightly.7
- 3.14.10-nightly.6
validations:
required: true
- type: dropdown
Expand Down
7 changes: 7 additions & 0 deletions openpype/hosts/fusion/plugins/create/create_saver.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ def remove_instances(self, instances):
def _imprint(self, tool, data):
# Save all data in a "openpype.{key}" = value data

# Instance id is the tool's name so we don't need to imprint as data
data.pop("instance_id", None)

active = data.pop("active", None)
if active is not None:
# Use active value to set the passthrough state
Expand Down Expand Up @@ -188,6 +191,10 @@ def get_managed_tool_data(self, tool):
passthrough = attrs["TOOLB_PassThrough"]
data["active"] = not passthrough

# Override publisher's UUID generation because tool names are
# already unique in Fusion in a comp
data["instance_id"] = tool.Name

return data

def get_pre_create_attr_defs(self):
Expand Down
108 changes: 104 additions & 4 deletions openpype/hosts/houdini/api/lib.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import sys
import os
import errno
import re
import uuid
import logging
Expand All @@ -9,10 +10,15 @@

import six

from openpype.lib import StringTemplate
from openpype.client import get_asset_by_name
from openpype.settings import get_current_project_settings
from openpype.pipeline import get_current_project_name, get_current_asset_name
from openpype.pipeline.context_tools import get_current_project_asset

from openpype.pipeline.context_tools import (
get_current_context_template_data,
get_current_project_asset
)
from openpype.widgets import popup
import hou


Expand Down Expand Up @@ -160,8 +166,6 @@ def validate_fps():

if current_fps != fps:

from openpype.widgets import popup

# Find main window
parent = hou.ui.mainQtWindow()
if parent is None:
Expand Down Expand Up @@ -747,3 +751,99 @@ def get_camera_from_container(container):

assert len(cameras) == 1, "Camera instance must have only one camera"
return cameras[0]


def get_context_var_changes():
"""get context var changes."""

houdini_vars_to_update = {}

project_settings = get_current_project_settings()
houdini_vars_settings = \
project_settings["houdini"]["general"]["update_houdini_var_context"]

if not houdini_vars_settings["enabled"]:
return houdini_vars_to_update

houdini_vars = houdini_vars_settings["houdini_vars"]

# No vars specified - nothing to do
if not houdini_vars:
return houdini_vars_to_update

# Get Template data
template_data = get_current_context_template_data()

# Set Houdini Vars
for item in houdini_vars:
# For consistency reasons we always force all vars to be uppercase
# Also remove any leading, and trailing whitespaces.
var = item["var"].strip().upper()

# get and resolve template in value
item_value = StringTemplate.format_template(
item["value"],
template_data
)

if var == "JOB" and item_value == "":
# sync $JOB to $HIP if $JOB is empty
item_value = os.environ["HIP"]

if item["is_directory"]:
item_value = item_value.replace("\\", "/")

current_value = hou.hscript("echo -n `${}`".format(var))[0]

if current_value != item_value:
houdini_vars_to_update[var] = (
current_value, item_value, item["is_directory"]
)

return houdini_vars_to_update


def update_houdini_vars_context():
"""Update asset context variables"""

for var, (_old, new, is_directory) in get_context_var_changes().items():
if is_directory:
try:
os.makedirs(new)
except OSError as e:
if e.errno != errno.EEXIST:
print(
"Failed to create ${} dir. Maybe due to "
"insufficient permissions.".format(var)
)

hou.hscript("set {}={}".format(var, new))
os.environ[var] = new
print("Updated ${} to {}".format(var, new))


def update_houdini_vars_context_dialog():
"""Show pop-up to update asset context variables"""
update_vars = get_context_var_changes()
if not update_vars:
# Nothing to change
print("Nothing to change, Houdini vars are already up to date.")
return

message = "\n".join(
"${}: {} -> {}".format(var, old or "None", new or "None")
for var, (old, new, _is_directory) in update_vars.items()
)

# TODO: Use better UI!
parent = hou.ui.mainQtWindow()
dialog = popup.Popup(parent=parent)
dialog.setModal(True)
dialog.setWindowTitle("Houdini scene has outdated asset variables")
dialog.setMessage(message)
dialog.setButtonText("Fix")

# on_show is the Fix button clicked callback
dialog.on_clicked.connect(update_houdini_vars_context)

dialog.show()
7 changes: 7 additions & 0 deletions openpype/hosts/houdini/api/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,9 @@ def on_save():

log.info("Running callback on save..")

# update houdini vars
lib.update_houdini_vars_context_dialog()

nodes = lib.get_id_required_nodes()
for node, new_id in lib.generate_ids(nodes):
lib.set_id(node, new_id, overwrite=False)
Expand Down Expand Up @@ -335,6 +338,9 @@ def on_open():

log.info("Running callback on open..")

# update houdini vars
lib.update_houdini_vars_context_dialog()

# Validate FPS after update_task_from_path to
# ensure it is using correct FPS for the asset
lib.validate_fps()
Expand Down Expand Up @@ -399,6 +405,7 @@ def _set_context_settings():
"""

lib.reset_framerange()
lib.update_houdini_vars_context()


def on_pyblish_instance_toggled(instance, new_value, old_value):
Expand Down
25 changes: 21 additions & 4 deletions openpype/hosts/houdini/api/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,14 @@ def create(self, subset_name, instance_data, pre_create_data):
self.customize_node_look(instance_node)

instance_data["instance_node"] = instance_node.path()
instance_data["instance_id"] = instance_node.path()
instance = CreatedInstance(
self.family,
subset_name,
instance_data,
self)
self._add_instance_to_context(instance)
imprint(instance_node, instance.data_to_store())
self.imprint(instance_node, instance.data_to_store())
return instance

except hou.Error as er:
Expand Down Expand Up @@ -222,25 +223,41 @@ def collect_instances(self):
self.cache_subsets(self.collection_shared_data)
for instance in self.collection_shared_data[
"houdini_cached_subsets"].get(self.identifier, []):

node_data = read(instance)

# Node paths are always the full node path since that is unique
# Because it's the node's path it's not written into attributes
# but explicitly collected
node_path = instance.path()
node_data["instance_id"] = node_path
node_data["instance_node"] = node_path

created_instance = CreatedInstance.from_existing(
read(instance), self
node_data, self
)
self._add_instance_to_context(created_instance)

def update_instances(self, update_list):
for created_inst, changes in update_list:
instance_node = hou.node(created_inst.get("instance_node"))

new_values = {
key: changes[key].new_value
for key in changes.changed_keys
}
imprint(
self.imprint(
instance_node,
new_values,
update=True
)

def imprint(self, node, values, update=False):
# Never store instance node and instance id since that data comes
# from the node's path
values.pop("instance_node", None)
values.pop("instance_id", None)
imprint(node, values, update=update)

def remove_instances(self, instances):
"""Remove specified instance from the scene.
Expand Down
8 changes: 8 additions & 0 deletions openpype/hosts/houdini/startup/MainMenuCommon.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ openpype.hosts.houdini.api.lib.reset_framerange()
]]></scriptCode>
</scriptItem>

<scriptItem id="update_context_vars">
<label>Update Houdini Vars</label>
<scriptCode><![CDATA[
import openpype.hosts.houdini.api.lib
openpype.hosts.houdini.api.lib.update_houdini_vars_context_dialog()
]]></scriptCode>
</scriptItem>

<separatorItem/>
<scriptItem id="experimental_tools">
<label>Experimental tools...</label>
Expand Down
17 changes: 7 additions & 10 deletions openpype/hosts/maya/api/menu.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import os
import logging
from functools import partial

from qtpy import QtWidgets, QtGui

import maya.utils
import maya.cmds as cmds

from openpype.settings import get_project_settings
from openpype.pipeline import (
get_current_project_name,
get_current_asset_name,
get_current_task_name
)
Expand Down Expand Up @@ -46,12 +45,12 @@ def get_context_label():
)


def install():
def install(project_settings):
if cmds.about(batch=True):
log.info("Skipping openpype.menu initialization in batch mode..")
return

def deferred():
def add_menu():
pyblish_icon = host_tools.get_pyblish_icon()
parent_widget = get_main_window()
cmds.menu(
Expand Down Expand Up @@ -191,7 +190,7 @@ def deferred():

cmds.setParent(MENU_NAME, menu=True)

def add_scripts_menu():
def add_scripts_menu(project_settings):
try:
import scriptsmenu.launchformaya as launchformaya
except ImportError:
Expand All @@ -201,9 +200,6 @@ def add_scripts_menu():
)
return

# load configuration of custom menu
project_name = get_current_project_name()
project_settings = get_project_settings(project_name)
config = project_settings["maya"]["scriptsmenu"]["definition"]
_menu = project_settings["maya"]["scriptsmenu"]["name"]

Expand All @@ -225,8 +221,9 @@ def add_scripts_menu():
# so that it only gets called after Maya UI has initialized too.
# This is crucial with Maya 2020+ which initializes without UI
# first as a QCoreApplication
maya.utils.executeDeferred(deferred)
cmds.evalDeferred(add_scripts_menu, lowestPriority=True)
maya.utils.executeDeferred(add_menu)
cmds.evalDeferred(partial(add_scripts_menu, project_settings),
lowestPriority=True)


def uninstall():
Expand Down
4 changes: 1 addition & 3 deletions openpype/hosts/maya/api/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
from openpype.pipeline import (
legacy_io,
get_current_project_name,
get_current_asset_name,
get_current_task_name,
register_loader_plugin_path,
register_inventory_action_path,
register_creator_plugin_path,
Expand Down Expand Up @@ -108,7 +106,7 @@ def install(self):
_set_project()
self._register_callbacks()

menu.install()
menu.install(project_settings)

register_event_callback("save", on_save)
register_event_callback("open", on_open)
Expand Down
Loading

0 comments on commit 958352e

Please sign in to comment.