Files
Machinist_700km/Plugins/HoudiniEngine/Content/Examples/Python/curve_input_example.py
T
Andron666 9c38e93fa4 part7
2022-12-05 20:31:35 +05:00

180 lines
7.4 KiB
Python

# Copyright (c) <2021> Side Effects Software Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. The name of Side Effects Software may not be used to endorse or
# promote products derived from this software without specific prior
# written permission.
#
# THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE "AS IS" AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
# NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
""" An example script that uses the API to instantiate an HDA and then
set 2 inputs: a geometry input (a cube) and a curve input (a helix). The
inputs are set during post instantiation (before the first cook). After the
first cook and output creation (post processing) the input structure is fetched
and logged.
"""
import math
import unreal
_g_wrapper = None
def get_test_hda_path():
return '/HoudiniEngine/Examples/hda/copy_to_curve_1_0.copy_to_curve_1_0'
def get_test_hda():
return unreal.load_object(None, get_test_hda_path())
def get_geo_asset_path():
return '/Engine/BasicShapes/Cube.Cube'
def get_geo_asset():
return unreal.load_object(None, get_geo_asset_path())
def configure_inputs(in_wrapper):
print('configure_inputs')
# Unbind from the delegate
in_wrapper.on_post_instantiation_delegate.remove_callable(configure_inputs)
# Create a geo input
geo_input = in_wrapper.create_empty_input(unreal.HoudiniPublicAPIGeoInput)
# Set the input objects/assets for this input
geo_object = get_geo_asset()
if not geo_input.set_input_objects((geo_object, )):
# If any errors occurred, get the last error message
print('Error on geo_input: {0}'.format(geo_input.get_last_error_message()))
# copy the input data to the HDA as node input 0
in_wrapper.set_input_at_index(0, geo_input)
# We can now discard the API input object
geo_input = None
# Create a curve input
curve_input = in_wrapper.create_empty_input(unreal.HoudiniPublicAPICurveInput)
# Create a curve wrapper/helper
curve_object = unreal.HoudiniPublicAPICurveInputObject(curve_input)
# Make it a Nurbs curve
curve_object.set_curve_type(unreal.HoudiniPublicAPICurveType.NURBS)
# Set the points of the curve, for this example we create a helix
# consisting of 100 points
curve_points = []
for i in range(100):
t = i / 20.0 * math.pi * 2.0
x = 100.0 * math.cos(t)
y = 100.0 * math.sin(t)
z = i
curve_points.append(unreal.Transform([x, y, z], [0, 0, 0], [1, 1, 1]))
curve_object.set_curve_points(curve_points)
# Error handling/message example: try to set geo_object on curve input
if not curve_input.set_input_objects((geo_object, )):
print('Error (example) while setting \'{0}\' on curve input: {1}'.format(
geo_object.get_name(), curve_input.get_last_error_message()
))
# Set the curve wrapper as an input object
curve_input.set_input_objects((curve_object, ))
# Copy the input data to the HDA as node input 1
in_wrapper.set_input_at_index(1, curve_input)
# We can now discard the API input object
curve_input = None
# Check for errors on the wrapper
last_error = in_wrapper.get_last_error_message()
if last_error:
print('Error on wrapper during input configuration: {0}'.format(last_error))
def print_api_input(in_input):
print('\t\tInput type: {0}'.format(in_input.__class__))
print('\t\tbKeepWorldTransform: {0}'.format(in_input.keep_world_transform))
print('\t\tbImportAsReference: {0}'.format(in_input.import_as_reference))
if isinstance(in_input, unreal.HoudiniPublicAPIGeoInput):
print('\t\tbPackBeforeMerge: {0}'.format(in_input.pack_before_merge))
print('\t\tbExportLODs: {0}'.format(in_input.export_lo_ds))
print('\t\tbExportSockets: {0}'.format(in_input.export_sockets))
print('\t\tbExportColliders: {0}'.format(in_input.export_colliders))
elif isinstance(in_input, unreal.HoudiniPublicAPICurveInput):
print('\t\tbCookOnCurveChanged: {0}'.format(in_input.cook_on_curve_changed))
print('\t\tbAddRotAndScaleAttributesOnCurves: {0}'.format(in_input.add_rot_and_scale_attributes_on_curves))
input_objects = in_input.get_input_objects()
if not input_objects:
print('\t\tEmpty input!')
else:
print('\t\tNumber of objects in input: {0}'.format(len(input_objects)))
for idx, input_object in enumerate(input_objects):
print('\t\t\tInput object #{0}: {1}'.format(idx, input_object))
if hasattr(in_input, 'get_object_transform_offset'):
print('\t\t\tObject Transform Offset: {0}'.format(in_input.get_object_transform_offset(input_object)))
if isinstance(input_object, unreal.HoudiniPublicAPICurveInputObject):
print('\t\t\tbClosed: {0}'.format(input_object.is_closed()))
print('\t\t\tCurveMethod: {0}'.format(input_object.get_curve_method()))
print('\t\t\tCurveType: {0}'.format(input_object.get_curve_type()))
print('\t\t\tReversed: {0}'.format(input_object.is_reversed()))
print('\t\t\tCurvePoints: {0}'.format(input_object.get_curve_points()))
def print_inputs(in_wrapper):
print('print_inputs')
# Unbind from the delegate
in_wrapper.on_post_processing_delegate.remove_callable(print_inputs)
# Fetch inputs, iterate over it and log
node_inputs = in_wrapper.get_inputs_at_indices()
parm_inputs = in_wrapper.get_input_parameters()
if not node_inputs:
print('No node inputs found!')
else:
print('Number of node inputs: {0}'.format(len(node_inputs)))
for input_index, input_wrapper in node_inputs.items():
print('\tInput index: {0}'.format(input_index))
print_api_input(input_wrapper)
if not parm_inputs:
print('No parameter inputs found!')
else:
print('Number of parameter inputs: {0}'.format(len(parm_inputs)))
for parm_name, input_wrapper in parm_inputs.items():
print('\tInput parameter name: {0}'.format(parm_name))
print_api_input(input_wrapper)
def run():
# get the API singleton
api = unreal.HoudiniPublicAPIBlueprintLib.get_api()
global _g_wrapper
# instantiate an asset with auto-cook enabled
_g_wrapper = api.instantiate_asset(get_test_hda(), unreal.Transform())
# Configure inputs on_post_instantiation, after instantiation, but before first cook
_g_wrapper.on_post_instantiation_delegate.add_callable(configure_inputs)
# Print the input state after the cook and output creation.
_g_wrapper.on_post_processing_delegate.add_callable(print_inputs)
if __name__ == '__main__':
run()