refactor: load mesh + object bpy ops
This commit is contained in:
+15
-1
@@ -27,18 +27,23 @@ ag_path = os.path.join(os.path.dirname(__file__))
|
||||
|
||||
# ensure_pip_packages()
|
||||
|
||||
|
||||
def get_python_files(path):
|
||||
return [f[:-3] for f in os.listdir(path) if f.endswith('.py')]
|
||||
|
||||
|
||||
def append_to_sys_path(path):
|
||||
if path not in sys.path:
|
||||
sys.path.append(path)
|
||||
|
||||
|
||||
def create_sam_model_dir():
|
||||
model_dir = os.path.join(ag_path, "../../models/sam")
|
||||
if not os.path.isdir(model_dir):
|
||||
os.makedirs(model_dir)
|
||||
add_model_folder_path('sam', model_dir)
|
||||
|
||||
|
||||
create_sam_model_dir()
|
||||
|
||||
paths = ['blender', 'sam', 'common']
|
||||
@@ -66,10 +71,19 @@ for file in files:
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(
|
||||
obj.NODE_DISPLAY_NAME_MAPPINGS())
|
||||
|
||||
if (hasattr(module, 'BLENDER_NODES')):
|
||||
for node in module.BLENDER_NODES:
|
||||
# print(node)
|
||||
# NODE_CLASS_MAPPINGS.update({node: module.BLENDER_NODES[node]})
|
||||
# NODE_DISPLAY_NAME_MAPPINGS.update({node: node})
|
||||
NODE_CLASS_MAPPINGS.update(node.NODE_CLASS_MAPPINGS())
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(
|
||||
node.NODE_DISPLAY_NAME_MAPPINGS())
|
||||
|
||||
if hasattr(module, 'NODE_CLASS_MAPPINGS'):
|
||||
NODE_CLASS_MAPPINGS.update(module.NODE_CLASS_MAPPINGS)
|
||||
if hasattr(module, 'NODE_DISPLAY_NAME_MAPPINGS'):
|
||||
NODE_DISPLAY_NAME_MAPPINGS.update(module.NODE_DISPLAY_NAME_MAPPINGS)
|
||||
|
||||
WEB_DIRECTORY = "js"
|
||||
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
|
||||
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
|
||||
|
||||
+120
-3
@@ -1,3 +1,5 @@
|
||||
import inspect
|
||||
import re
|
||||
BPY_OBJS = "BPY_OBJS"
|
||||
BPY_OBJ = "BPY_OBJ"
|
||||
|
||||
@@ -5,7 +7,16 @@ BPY_OBJS_TYPE = {
|
||||
BPY_OBJS: (BPY_OBJS,),
|
||||
}
|
||||
|
||||
|
||||
class ObjectOps:
|
||||
@classmethod
|
||||
def get_extra_input_types(cls, bpy):
|
||||
return cls.EXTRA_INPUT_TYPES
|
||||
|
||||
@classmethod
|
||||
def get_base_input_types(cls, bpy):
|
||||
return cls.BASE_INPUT_TYPES
|
||||
|
||||
EXTRA_INPUT_TYPES = {}
|
||||
BASE_INPUT_TYPES = {
|
||||
"BPY_OBJ": ("BPY_OBJ",)
|
||||
@@ -13,14 +24,17 @@ class ObjectOps:
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
import global_bpy
|
||||
bpy = global_bpy.get_bpy()
|
||||
# print(cls.BASE_INPUT_TYPES)
|
||||
# print(cls.EXTRA_INPUT_TYPES)
|
||||
result = {
|
||||
"required": {
|
||||
**cls.BASE_INPUT_TYPES,
|
||||
**cls.EXTRA_INPUT_TYPES
|
||||
**cls.get_base_input_types(bpy),
|
||||
**cls.get_extra_input_types(bpy)
|
||||
}
|
||||
}
|
||||
# print(result)
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
@@ -33,7 +47,7 @@ class ObjectOps:
|
||||
def NODE_DISPLAY_NAME_MAPPINGS(cls):
|
||||
import re
|
||||
return {
|
||||
cls.__name__: re.sub("([a-z])([A-Z])","\g<1> \g<2>",cls.__name__)
|
||||
cls.__name__: re.sub("([a-z])([A-Z])", "\g<1> \g<2>", cls.__name__)
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BPY_OBJ",)
|
||||
@@ -74,3 +88,106 @@ class EditOps(ObjectOps):
|
||||
return (props["BPY_OBJ"], )
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def map_args(bpy, func):
|
||||
print(func, type(func))
|
||||
|
||||
if str(type(func)) == "<class 'bpy_func'>":
|
||||
func = func.__init__
|
||||
print(func)
|
||||
print(dir(func))
|
||||
|
||||
if callable(func):
|
||||
sig = inspect.signature(func)
|
||||
print(sig)
|
||||
args_dict = {
|
||||
name: param.default
|
||||
for name, param in sig.parameters.items()
|
||||
if param.default is not inspect.Parameter.empty
|
||||
}
|
||||
print(args_dict)
|
||||
return args_dict
|
||||
|
||||
|
||||
|
||||
# if isinstance(func, bpy.types.Function):
|
||||
# print('is class')
|
||||
# func = func.__init__
|
||||
|
||||
rna_type = func.get_rna_type()
|
||||
args_dict = {}
|
||||
for prop in rna_type.properties:
|
||||
if prop.is_readonly:
|
||||
continue
|
||||
prop_type = str(prop.type)
|
||||
prop_dict = {}
|
||||
if prop_type in ["INT", "FLOAT"]:
|
||||
prop_dict.update(
|
||||
{"min": prop.hard_min, "max": prop.hard_max, "default": prop.default})
|
||||
elif prop_type == "BOOLEAN":
|
||||
prop_dict.update({"default": prop.default})
|
||||
elif prop_type == "STRING":
|
||||
prop_dict.update(
|
||||
{"default": prop.default, "multiline": False})
|
||||
elif prop_type == "ENUM":
|
||||
enum_items = [item.identifier for item in prop.enum_items]
|
||||
args_dict[prop.identifier] = (enum_items,)
|
||||
|
||||
# print(enum_items)
|
||||
|
||||
if args_dict.get(prop.identifier) is None:
|
||||
args_dict[prop.identifier] = (prop_type, prop_dict)
|
||||
|
||||
# print(args_dict)
|
||||
return args_dict
|
||||
|
||||
|
||||
def camel_to_snake(name):
|
||||
name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
|
||||
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()
|
||||
|
||||
|
||||
def snake_to_camel(snake_str):
|
||||
components = snake_str.split('_')
|
||||
# capitalize the first letter of each component and join them together
|
||||
camel_str = ''.join(x.title() for x in components)
|
||||
return camel_str
|
||||
|
||||
|
||||
def get_nested_attr(obj, attr_str):
|
||||
attrs = attr_str.split('.')
|
||||
for attr in attrs:
|
||||
obj = getattr(obj, attr)
|
||||
return obj
|
||||
|
||||
|
||||
def print_blender_functions(path):
|
||||
import sys
|
||||
import os
|
||||
|
||||
ag_path = os.path.join(os.path.dirname(__file__), '../')
|
||||
if ag_path not in sys.path:
|
||||
sys.path.append(ag_path)
|
||||
|
||||
import global_bpy
|
||||
bpy = global_bpy.get_bpy()
|
||||
|
||||
print(dir(get_nested_attr(bpy, path)), type(get_nested_attr(bpy, path)))
|
||||
|
||||
|
||||
def create_ops_class(cls, path, name=None):
|
||||
node_name = snake_to_camel(
|
||||
name if name is not None else path.split('.')[-1])
|
||||
print(node_name)
|
||||
return type(
|
||||
node_name, (cls, object),
|
||||
{
|
||||
'get_extra_input_types': classmethod(
|
||||
lambda cls, bpy: {
|
||||
**map_args(bpy, get_nested_attr(bpy, path))}
|
||||
),
|
||||
'blender_process': lambda self, bpy, BPY_OBJ, **props:
|
||||
(get_nested_attr(bpy, path)(**props), None)[1]
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import blender_node
|
||||
|
||||
|
||||
class CreateVertexGroupOps(blender_node.EditOps):
|
||||
EXTRA_INPUT_TYPES = {
|
||||
"name": ("STRING", {
|
||||
"multiline": False,
|
||||
"default": "Group"
|
||||
}),
|
||||
}
|
||||
|
||||
def blender_process(self, bpy, BPY_OBJ, name, **props):
|
||||
bpy.context.object.vertex_groups.new(name=name)
|
||||
@@ -1,10 +0,0 @@
|
||||
import blender_node
|
||||
|
||||
|
||||
class EditDeleteOps(blender_node.EditOps):
|
||||
EXTRA_INPUT_TYPES = {
|
||||
"type": (['VERT', 'EDGE', 'FACE', 'EDGE_FACE', 'ONLY_FACE'],),
|
||||
}
|
||||
|
||||
def blender_process(self, bpy, BPY_OBJ, **props):
|
||||
bpy.ops.mesh.delete(**props)
|
||||
@@ -0,0 +1,24 @@
|
||||
import blender_node
|
||||
|
||||
mesh_api = ['attribute_set', 'average_normals', 'beautify_fill', 'bevel', 'bisect', 'blend_from_shape', 'bridge_edge_loops', 'colors_reverse', 'colors_rotate', 'convex_hull', 'customdata_bevel_weight_edge_add', 'customdata_bevel_weight_edge_clear', 'customdata_bevel_weight_vertex_add', 'customdata_bevel_weight_vertex_clear', 'customdata_crease_edge_add', 'customdata_crease_edge_clear', 'customdata_crease_vertex_add', 'customdata_crease_vertex_clear', 'customdata_custom_splitnormals_add', 'customdata_custom_splitnormals_clear', 'customdata_mask_clear', 'customdata_skin_add', 'customdata_skin_clear', 'decimate', 'delete', 'delete_edgeloop', 'delete_loose', 'dissolve_degenerate', 'dissolve_edges', 'dissolve_faces', 'dissolve_limited', 'dissolve_mode', 'dissolve_verts', 'dupli_extrude_cursor', 'duplicate', 'duplicate_move', 'edge_collapse', 'edge_face_add', 'edge_rotate', 'edge_split', 'edgering_select', 'edges_select_sharp', 'extrude_context', 'extrude_context_move', 'extrude_edges_indiv', 'extrude_edges_move', 'extrude_faces_indiv', 'extrude_faces_move', 'extrude_manifold', 'extrude_region', 'extrude_region_move', 'extrude_region_shrink_fatten', 'extrude_repeat', 'extrude_vertices_move', 'extrude_verts_indiv', 'face_make_planar', 'face_set_extract', 'face_split_by_edges', 'faces_mirror_uv', 'faces_select_linked_flat', 'faces_shade_flat', 'faces_shade_smooth', 'fill', 'fill_grid', 'fill_holes', 'flip_normals', 'flip_quad_tessellation', 'hide', 'inset', 'intersect', 'intersect_boolean', 'knife_project', 'knife_tool', 'loop_multi_select', 'loop_select', 'loop_to_region', 'loopcut', 'loopcut_slide', 'mark_freestyle_edge', 'mark_freestyle_face', 'mark_seam', 'mark_sharp', 'merge', 'merge_normals',
|
||||
'mod_weighted_strength', 'normals_make_consistent', 'normals_tools', 'offset_edge_loops', 'offset_edge_loops_slide', 'paint_mask_extract', 'paint_mask_slice', 'point_normals', 'poke', 'polybuild_delete_at_cursor', 'polybuild_dissolve_at_cursor', 'polybuild_extrude_at_cursor_move', 'polybuild_face_at_cursor', 'polybuild_face_at_cursor_move', 'polybuild_split_at_cursor', 'polybuild_split_at_cursor_move', 'polybuild_transform_at_cursor', 'polybuild_transform_at_cursor_move', 'primitive_circle_add', 'primitive_cone_add', 'primitive_cube_add', 'primitive_cube_add_gizmo', 'primitive_cylinder_add', 'primitive_grid_add', 'primitive_ico_sphere_add', 'primitive_monkey_add', 'primitive_plane_add', 'primitive_torus_add', 'primitive_uv_sphere_add', 'quads_convert_to_tris', 'region_to_loop', 'remove_doubles', 'reveal', 'rip', 'rip_edge', 'rip_edge_move', 'rip_move', 'screw', 'select_all', 'select_axis', 'select_face_by_sides', 'select_interior_faces', 'select_less', 'select_linked', 'select_linked_pick', 'select_loose', 'select_mirror', 'select_mode', 'select_more', 'select_next_item', 'select_non_manifold', 'select_nth', 'select_prev_item', 'select_random', 'select_similar', 'select_similar_region', 'select_ungrouped', 'separate', 'set_normals_from_faces', 'shape_propagate_to_all', 'shortest_path_pick', 'shortest_path_select', 'smooth_normals', 'solidify', 'sort_elements', 'spin', 'split', 'split_normals', 'subdivide', 'subdivide_edgering', 'symmetrize', 'symmetry_snap', 'tris_convert_to_quads', 'unsubdivide', 'uv_texture_add', 'uv_texture_remove', 'uvs_reverse', 'uvs_rotate', 'vert_connect', 'vert_connect_concave', 'vert_connect_nonplanar', 'vert_connect_path', 'vertices_smooth', 'vertices_smooth_laplacian', 'wireframe']
|
||||
|
||||
object_api = ['add', 'add_named', 'align', 'anim_transforms_to_deltas', 'armature_add', 'assign_property_defaults', 'bake', 'bake_image', 'camera_add', 'clear_override_library', 'collection_add', 'collection_external_asset_drop', 'collection_instance_add', 'collection_link', 'collection_objects_select', 'collection_remove', 'collection_unlink', 'constraint_add', 'constraint_add_with_targets', 'constraints_clear', 'constraints_copy', 'convert', 'correctivesmooth_bind', 'curves_empty_hair_add', 'curves_random_add', 'data_instance_add', 'data_transfer', 'datalayout_transfer', 'delete', 'drop_geometry_nodes', 'drop_named_image', 'drop_named_material', 'duplicate', 'duplicate_move', 'duplicate_move_linked', 'duplicates_make_real', 'editmode_toggle', 'effector_add', 'empty_add', 'explode_refresh', 'face_map_add', 'face_map_assign', 'face_map_deselect', 'face_map_move', 'face_map_remove', 'face_map_remove_from', 'face_map_select', 'forcefield_toggle', 'geometry_node_tree_copy_assign', 'geometry_nodes_input_attribute_toggle', 'geometry_nodes_move_to_nodes', 'gpencil_add', 'gpencil_modifier_add', 'gpencil_modifier_apply', 'gpencil_modifier_copy', 'gpencil_modifier_copy_to_selected', 'gpencil_modifier_move_down', 'gpencil_modifier_move_to_index', 'gpencil_modifier_move_up', 'gpencil_modifier_remove', 'hide_collection', 'hide_render_clear_all', 'hide_view_clear', 'hide_view_set', 'hook_add_newob', 'hook_add_selob', 'hook_assign', 'hook_recenter', 'hook_remove', 'hook_reset', 'hook_select', 'instance_offset_from_cursor', 'instance_offset_from_object', 'instance_offset_to_cursor', 'isolate_type_render', 'join', 'join_shapes', 'join_uvs', 'laplaciandeform_bind', 'light_add', 'lightprobe_add', 'lightprobe_cache_bake', 'lightprobe_cache_free', 'lineart_bake_strokes', 'lineart_bake_strokes_all', 'lineart_clear', 'lineart_clear_all', 'link_to_collection', 'load_background_image', 'load_reference_image', 'location_clear', 'make_dupli_face', 'make_links_data', 'make_links_scene', 'make_local', 'make_override_library', 'make_single_user', 'material_slot_add', 'material_slot_assign', 'material_slot_copy', 'material_slot_deselect', 'material_slot_move', 'material_slot_remove', 'material_slot_remove_unused', 'material_slot_select', 'meshdeform_bind', 'metaball_add', 'mode_set', 'mode_set_with_submode', 'modifier_add', 'modifier_apply', 'modifier_apply_as_shapekey', 'modifier_convert', 'modifier_copy', 'modifier_copy_to_selected', 'modifier_move_down',
|
||||
'modifier_move_to_index', 'modifier_move_up', 'modifier_remove', 'modifier_set_active', 'move_to_collection', 'multires_base_apply', 'multires_external_pack', 'multires_external_save', 'multires_higher_levels_delete', 'multires_rebuild_subdiv', 'multires_reshape', 'multires_subdivide', 'multires_unsubdivide', 'ocean_bake', 'origin_clear', 'origin_set', 'parent_clear', 'parent_inverse_apply', 'parent_no_inverse_set', 'parent_set', 'particle_system_add', 'particle_system_remove', 'paths_calculate', 'paths_clear', 'paths_update', 'paths_update_visible', 'pointcloud_add', 'posemode_toggle', 'quadriflow_remesh', 'quick_explode', 'quick_fur', 'quick_liquid', 'quick_smoke', 'randomize_transform', 'reset_override_library', 'rotation_clear', 'scale_clear', 'select_all', 'select_by_type', 'select_camera', 'select_grouped', 'select_hierarchy', 'select_less', 'select_linked', 'select_mirror', 'select_more', 'select_pattern', 'select_random', 'select_same_collection', 'shade_flat', 'shade_smooth', 'shaderfx_add', 'shaderfx_copy', 'shaderfx_move_down', 'shaderfx_move_to_index', 'shaderfx_move_up', 'shaderfx_remove', 'shape_key_add', 'shape_key_clear', 'shape_key_mirror', 'shape_key_move', 'shape_key_remove', 'shape_key_retime', 'shape_key_transfer', 'simulation_nodes_cache_bake', 'simulation_nodes_cache_calculate_to_frame', 'simulation_nodes_cache_delete', 'skin_armature_create', 'skin_loose_mark_clear', 'skin_radii_equalize', 'skin_root_mark', 'speaker_add', 'subdivision_set', 'surfacedeform_bind', 'text_add', 'track_clear', 'track_set', 'transfer_mode', 'transform_apply', 'transform_axis_target', 'transform_to_mouse', 'transforms_to_deltas', 'unlink_data', 'vertex_group_add', 'vertex_group_assign', 'vertex_group_assign_new', 'vertex_group_clean', 'vertex_group_copy', 'vertex_group_copy_to_selected', 'vertex_group_deselect', 'vertex_group_invert', 'vertex_group_levels', 'vertex_group_limit_total', 'vertex_group_lock', 'vertex_group_mirror', 'vertex_group_move', 'vertex_group_normalize', 'vertex_group_normalize_all', 'vertex_group_quantize', 'vertex_group_remove', 'vertex_group_remove_from', 'vertex_group_select', 'vertex_group_set_active', 'vertex_group_smooth', 'vertex_group_sort', 'vertex_parent_set', 'vertex_weight_copy', 'vertex_weight_delete', 'vertex_weight_normalize_active_vertex', 'vertex_weight_paste', 'vertex_weight_set_active', 'visual_transform_apply', 'volume_add', 'volume_import', 'voxel_remesh', 'voxel_size_edit']
|
||||
|
||||
BLENDER_NODES = [
|
||||
blender_node.create_ops_class(
|
||||
blender_node.EditOps, 'ops.mesh.' + op) for op in mesh_api
|
||||
] + [
|
||||
blender_node.create_ops_class(
|
||||
blender_node.ObjectOps, 'ops.object.' + op) for op in object_api
|
||||
]
|
||||
|
||||
# + [
|
||||
# blender_node.create_ops_class(
|
||||
# blender_node.ObjectOps, 'context.object.vertex_groups.new', 'create_new_vertex_group'),
|
||||
# ]
|
||||
|
||||
# print(blender_node.print_blender_functions('ops','object'))
|
||||
# print(blender_node.print_blender_functions('context.object'))
|
||||
# print(blender_node.print_blender_functions('context.object.vertex_groups.new'))
|
||||
@@ -1,10 +0,0 @@
|
||||
import blender_node
|
||||
|
||||
|
||||
class MeshSelectAllOps(blender_node.EditOps):
|
||||
EXTRA_INPUT_TYPES = {
|
||||
"action": (['SELECT', 'TOGGLE', 'DESELECT', 'INVERT'],),
|
||||
}
|
||||
|
||||
def blender_process(self, bpy, BPY_OBJ, **props):
|
||||
bpy.ops.mesh.select_all(**props)
|
||||
Reference in New Issue
Block a user