OverviewFilesCommitsIssuesDocsReleasesPeers

hardops / test_rest.py

140 lines · python ref:
import bpy, math, gpu

gpu.init()
bpy.ops.preferences.addon_enable(module='bl_ext.user_default.hardops')

from bl_ext.user_default.hardops.utility.geometry_nodes import compat
from bl_ext.user_default.hardops.operators.modals import radial_array_nodes
from bl_ext.user_default.hardops.operators.modals import ever_scroll
from bl_ext.user_default.hardops.ui_framework.operator_ui import Master

Master.draw = lambda self, *args, **kwargs: None

print("\nRNA_INPUTS:", compat.RNA_INPUTS)

# ---------------------------------------------------------------- radial array
bpy.ops.mesh.primitive_cube_add()
obj = bpy.context.active_object

node_group = radial_array_nodes.radial_array_nodes()
mod = obj.modifiers.new('HOPS_Radial_Array', 'NODES')
mod.node_group = node_group

array = radial_array_nodes.RadArray(mod)
print("\nRadArray defaults: count", array.count, "rotation", array.rotation, "offset", array.offset)

array.set_defaults()
assert array.count == 3, array.count
assert array.rotation == 360.0, array.rotation
assert tuple(array.axis) == (0.0, 0.0, 1.0), tuple(array.axis)
assert array.full_circle is True
assert array.self is obj

array.count = 7
assert array.count == 7
array.offset = 2.5
assert abs(array.offset - 2.5) < 1e-6
array.pivot_offset = (1.0, 2.0, 3.0)
assert tuple(array.pivot_offset) == (1.0, 2.0, 3.0), tuple(array.pivot_offset)
array.rotation_offset = (0.0, 0.5, 0.0)
assert tuple(array.rotation_offset) == (0.0, 0.5, 0.0)
array.center_pivot = True
assert array.center_pivot is True
print("RadArray round trips OK")

dg = bpy.context.evaluated_depsgraph_get()
me = obj.evaluated_get(dg).to_mesh()
print("radial array evaluated verts:", len(me.vertices))
assert len(me.vertices) == 8 * 7, len(me.vertices)

# ------------------------------------------------------------------ to_thread
bpy.ops.mesh.primitive_cylinder_add(vertices=16, radius=0.5, depth=1.0, location=(5, 0, 0))
cyl = bpy.context.active_object
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
# modal operators can't be invoked in background, so drive its modifier code directly
from bl_ext.user_default.hardops.operators.editmode.to_thread import HOPS_OT_ToThread

import types

op = types.SimpleNamespace()
for name in ('new_modifier', 'get_modifier', 'backup_modifier', 'restore_modifier', 'refresh_modifier', 'generate_unique_name'):
    setattr(op, name, types.MethodType(getattr(HOPS_OT_ToThread, name), op))
thread_mod, table = op.new_modifier(cyl)
print("\nto_thread modifier:", thread_mod.name, "sockets:", len(table))

backup = op.backup_modifier(thread_mod, table)
print("backup:", backup)
assert backup, 'empty backup'

inputs = compat.ModifierInputs(thread_mod)
inputs[table['Depth']] = 0.42
inputs[table['Turns']] = 5
assert abs(inputs[table['Depth']] - 0.42) < 1e-6

op.restore_modifier(thread_mod, table, backup)
assert abs(inputs[table['Depth']] - backup['Depth']) < 1e-6, (inputs[table['Depth']], backup['Depth'])
print("to_thread backup/restore OK")

cyl.update_from_editmode() # invoke() does this before get_modifier
found_mod, found_table = op.get_modifier(cyl)
assert found_mod == thread_mod, (found_mod, thread_mod)
print("to_thread get_modifier OK")

bpy.ops.object.mode_set(mode='OBJECT')

# ---------------------------------------------------- attribute driven inputs
ng = bpy.data.node_groups.new('attr_probe', 'GeometryNodeTree')
ng.interface.new_socket('Geometry', in_out='INPUT', socket_type='NodeSocketGeometry')
value = ng.interface.new_socket('Value', in_out='INPUT', socket_type='NodeSocketFloat')
ng.interface.new_socket('Geometry', in_out='OUTPUT', socket_type='NodeSocketGeometry')
out = ng.interface.new_socket('Weight', in_out='OUTPUT', socket_type='NodeSocketFloat')

bpy.ops.mesh.primitive_cube_add(location=(10, 0, 0))
attr_obj = bpy.context.active_object
attr_mod = attr_obj.modifiers.new('attr_probe', 'NODES')
attr_mod.node_group = ng

assert compat.supports_attribute(attr_mod, value.identifier)
assert compat.get_use_attribute(attr_mod, value.identifier) is False

data, prop = compat.value_prop(attr_mod, value.identifier)
assert data is not None and data.bl_rna.properties[prop]

bpy.ops.object.geometry_nodes_input_attribute_toggle(input_name=value.identifier, modifier_name=attr_mod.name)
assert compat.get_use_attribute(attr_mod, value.identifier) is True, 'attribute toggle not reflected'

bpy.ops.hops.helper_node_attr_set(modifier=attr_mod.name, attribute=value.identifier, value='position')
assert compat.get_attribute_name(attr_mod, value.identifier) == 'position', compat.get_attribute_name(attr_mod, value.identifier)

data, prop = compat.attribute_name_prop(attr_mod, value.identifier)
assert getattr(data, prop) == 'position'

data, prop = compat.output_attribute_name_prop(attr_mod, out.identifier)
assert data is not None, 'no output attribute prop'
bpy.ops.hops.helper_node_attr_set(modifier=attr_mod.name, attribute=out.identifier, value='out_attr', is_output=True)
assert getattr(data, prop) == 'out_attr', getattr(data, prop)
print("\nattribute inputs/outputs OK")

# ---------------------------------------------------------------- ever_scroll
ng2 = bpy.data.node_groups.new('objinfo_probe', 'GeometryNodeTree')
ng2.interface.new_socket('Geometry', in_out='INPUT', socket_type='NodeSocketGeometry')
obj_socket = ng2.interface.new_socket('Cutter', in_out='INPUT', socket_type='NodeSocketObject')
ng2.interface.new_socket('Geometry', in_out='OUTPUT', socket_type='NodeSocketGeometry')

group_in = ng2.nodes.new('NodeGroupInput')
obj_info = ng2.nodes.new('GeometryNodeObjectInfo')
ng2.links.new(group_in.outputs[obj_socket.identifier], obj_info.inputs['Object'])

bpy.ops.mesh.primitive_cube_add(location=(20, 0, 0))
scroll_obj = bpy.context.active_object
scroll_mod = scroll_obj.modifiers.new('objinfo_probe', 'NODES')
scroll_mod.node_group = ng2
compat.ModifierInputs(scroll_mod)[obj_socket.identifier] = cyl

found = ever_scroll.get_node_graph_objects(scroll_mod)
print("\nget_node_graph_objects ->", found)
assert found == [cyl], found

print("\nALL CHECKS PASSED")