Created
September 1, 2024 07:45
-
-
Save nemurigi/f001e43b611fc1b562d865b18583412c to your computer and use it in GitHub Desktop.
VRC Houdini勉強会No.92
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import hou | |
| def get_declare(name, attrib): | |
| data_type = attrib.dataType() | |
| size = attrib.size() | |
| attrib_name = attrib.name() | |
| if not (data_type == hou.attribData.Float or data_type == hou.attribData.Int): | |
| return '' | |
| if data_type == hou.attribData.Int: | |
| return f'static const int {name}_{attrib_name}' | |
| if size == 1: | |
| return f'static const float {name}_{attrib_name}' | |
| elif size == 2: | |
| return f'static const float2 {name}_{attrib_name}' | |
| elif size == 3: | |
| return f'static const float3 {name}_{attrib_name}' | |
| elif size == 4: | |
| return f'static const float4 {name}_{attrib_name}' | |
| return '' | |
| def get_element(value, element_size, data_type, precision = 5): | |
| if not(data_type == hou.attribData.Float or data_type == hou.attribData.Int): | |
| return '' | |
| if data_type == hou.attribData.Int: | |
| return f"{value}" | |
| if element_size == 1: | |
| return f"{value:.{precision}f}" | |
| elif element_size == 2: | |
| return f"float2({value[0]:.{precision}f}, {value[1]:.{precision}f})" | |
| elif element_size == 3: | |
| return f"float3({value[0]:.{precision}f}, {value[1]:.{precision}f}, {value[2]:.{precision}f})" | |
| elif element_size == 4: | |
| return f"float4({value[0]:.{precision}f}, {value[1]:.{precision}f}, {value[2]:.{precision}f}, {value[3]:.{precision}f})" | |
| else: | |
| return '' | |
| def get_non_array_variable(geo, name, attrib, precision=5): | |
| data_type = attrib.dataType() | |
| attrib_name = attrib.name() | |
| element_size = attrib.size() | |
| value = geo.attribValue(attrib_name) | |
| if not(data_type == hou.attribData.Float or data_type == hou.attribData.Int): | |
| return '' | |
| return f'{get_declare(name, attrib)} = {get_element(value, element_size, data_type)};\n' | |
| def get_array_variable(geo, name, attrib): | |
| attrib_name = attrib.name() | |
| attrib_type = attrib.type() | |
| data_type = attrib.dataType() | |
| element_size : int = attrib.size() | |
| if not(data_type == hou.attribData.Float or data_type == hou.attribData.Int): | |
| return '' | |
| if attrib_type == hou.attribType.Point: | |
| if data_type == hou.attribData.Int: | |
| data = geo.pointIntAttribValues(attrib_name) | |
| elif data_type == hou.attribData.Float: | |
| data = geo.pointFloatAttribValues(attrib_name) | |
| else: | |
| return '' | |
| elif attrib_type == hou.attribType.Prim: | |
| if data_type == hou.attribData.Int: | |
| data = geo.primIntAttribValues(attrib_name) | |
| elif data_type == hou.attribData.Float: | |
| data = geo.primFloatAttribValues(attrib_name) | |
| else: | |
| return '' | |
| elif attrib_type == hou.attribType.Global: | |
| if data_type == hou.attribData.Int: | |
| data = geo.intListAttribValue(attrib_name) | |
| elif data_type == hou.attribData.Float: | |
| data = geo.floatListAttribValue(attrib_name) | |
| else: | |
| return '' | |
| else: | |
| return '' | |
| array_size = len(data) // element_size | |
| declare = get_declare(name, attrib) + f'[{array_size}] = {{ \n' | |
| array_variable = '' | |
| if element_size > 2: | |
| attrib_values = [data[i*element_size:(i+1)*element_size] for i in range(array_size)] | |
| else: | |
| attrib_values = data | |
| for value in attrib_values: | |
| array_variable += ' ' + get_element(value, element_size, data_type) + ',\n' | |
| return declare + array_variable + '};\n' | |
| def main(): | |
| node = hou.pwd() | |
| geo = node.geometry() | |
| # get HDA parameters | |
| parent = node.parent() | |
| name : str = parent.evalParm('name') | |
| output_file_path = parent.evalParm("path") | |
| debug_mode = parent.evalParm("debug_mode") | |
| point_attribs = parent.evalParm("point_attribs").split(' ') | |
| prim_attribs = parent.evalParm("prim_attribs").split(' ') | |
| detail_attribs = parent.evalParm("detail_attribs").split(' ') | |
| # detail attributes | |
| details = '// detail attributes \n' | |
| for attrib_name in detail_attribs: | |
| attrib = geo.findGlobalAttrib(attrib_name) | |
| if not attrib: | |
| continue | |
| if not attrib.isArrayType(): | |
| details += get_non_array_variable(geo, name, attrib) | |
| else: | |
| details += get_array_variable(geo, name, attrib) | |
| # point attributes | |
| points = '// point attributes \n' | |
| for attrib_name in point_attribs: | |
| attrib = geo.findPointAttrib(attrib_name) | |
| if not attrib: | |
| continue | |
| points += get_array_variable(geo, name, attrib) | |
| # prim attributes | |
| prims = '// prim attributes \n' | |
| for attrib_name in prim_attribs: | |
| attrib = geo.findPrimAttrib(attrib_name) | |
| if not attrib: | |
| continue | |
| prims += get_array_variable(geo, name, attrib) | |
| # preprocessor | |
| macro = ascii(name)[1:-1].upper() | |
| text = '\n'.join([ | |
| f'#ifndef {macro}_INCLUDED \n#define {macro}_INCLUDED \n', | |
| details, | |
| points, | |
| prims, | |
| '#endif' | |
| ]) | |
| if debug_mode == 1: | |
| print("-------------------") | |
| print(text) | |
| print("-------------------") | |
| with open(output_file_path, mode='w') as file: | |
| file.write(text) | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment