Skip to content

Instantly share code, notes, and snippets.

@nemurigi
Created September 1, 2024 07:45
Show Gist options
  • Select an option

  • Save nemurigi/f001e43b611fc1b562d865b18583412c to your computer and use it in GitHub Desktop.

Select an option

Save nemurigi/f001e43b611fc1b562d865b18583412c to your computer and use it in GitHub Desktop.
VRC Houdini勉強会No.92
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