From dfdc97b27b2ee154a467de95524c7a03bb89596a Mon Sep 17 00:00:00 2001 From: Radionic Date: Fri, 29 Sep 2023 13:13:55 +0800 Subject: [PATCH] chore: remove unused nodes --- __init__.py | 2 +- blender/combine_mesh.py | 35 --------- blender/create_vertex_bounds.py | 63 ----------------- blender/create_vertex_group.py | 56 --------------- blender/disolve_faces.py | 61 ---------------- blender/fill_face.py | 46 ------------ blender/group_object.py | 30 -------- blender/group_vertex_inside.py | 108 ---------------------------- blender/knift_project.py | 121 -------------------------------- blender/mesh_from_texture.py | 104 --------------------------- blender/open_in_blender.py | 48 ------------- blender/plane.py | 74 ------------------- blender/scale_vertex.py | 55 --------------- blender/texture.py | 92 ------------------------ blender/transform_object.py | 45 ------------ common/point_visualizer.py | 52 -------------- common/vector3d.py | 45 ------------ sam/avatar_segmentation.py | 67 ------------------ sam/sam_load_emb.py | 52 -------------- sam/sam_loader.py | 42 ----------- sam/sam_node_from_emb.py | 110 ----------------------------- sam/sam_node_remote.py | 88 ----------------------- sam/sam_prompt.py | 68 ------------------ sam/sam_save_emb.py | 64 ----------------- 24 files changed, 1 insertion(+), 1527 deletions(-) delete mode 100644 blender/combine_mesh.py delete mode 100644 blender/create_vertex_bounds.py delete mode 100644 blender/create_vertex_group.py delete mode 100644 blender/disolve_faces.py delete mode 100644 blender/fill_face.py delete mode 100644 blender/group_object.py delete mode 100644 blender/group_vertex_inside.py delete mode 100644 blender/knift_project.py delete mode 100644 blender/mesh_from_texture.py delete mode 100644 blender/open_in_blender.py delete mode 100644 blender/plane.py delete mode 100644 blender/scale_vertex.py delete mode 100644 blender/texture.py delete mode 100644 blender/transform_object.py delete mode 100644 common/point_visualizer.py delete mode 100644 common/vector3d.py delete mode 100644 sam/avatar_segmentation.py delete mode 100644 sam/sam_load_emb.py delete mode 100644 sam/sam_loader.py delete mode 100644 sam/sam_node_from_emb.py delete mode 100644 sam/sam_node_remote.py delete mode 100644 sam/sam_prompt.py delete mode 100644 sam/sam_save_emb.py diff --git a/__init__.py b/__init__.py index 56c20c6..36d3483 100644 --- a/__init__.py +++ b/__init__.py @@ -72,7 +72,7 @@ def download_sam_model(): download_sam_model() -paths = ["blender", "sam", "common"] +paths = ["blender", "sam"] files = [] for path in paths: diff --git a/blender/combine_mesh.py b/blender/combine_mesh.py deleted file mode 100644 index 27594fa..0000000 --- a/blender/combine_mesh.py +++ /dev/null @@ -1,35 +0,0 @@ -class CombineMesh: - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "obj_1": ("BPY_OBJS",), - "obj_2": ("BPY_OBJS",), - }, - } - - RETURN_TYPES = ("BPY_OBJS",) - RETURN_NAMES = ("bpy_objs",) - - FUNCTION = "process" - - CATEGORY = "mesh" - - def process(self, obj_1, obj_2): - import global_bpy - bpy = global_bpy.get_bpy() - - override = bpy.context.copy() - override["active_object"] = obj_1[0] - override["selected_editable_objects"] = list([*obj_1, *obj_2]) - bpy.ops.object.join(override) - joined_object = override["active_object"] - return ([joined_object], ) - -NODE_CLASS_MAPPINGS = { - "CombineMesh": CombineMesh -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "CombineMesh": "Combine Mesh" -} diff --git a/blender/create_vertex_bounds.py b/blender/create_vertex_bounds.py deleted file mode 100644 index 21bc24f..0000000 --- a/blender/create_vertex_bounds.py +++ /dev/null @@ -1,63 +0,0 @@ -class CreateVertexBounds(): - @classmethod - def INPUT_TYPES(s): - - return { - "required": { - "bpy_objs_target": ("BPY_OBJS",), - "name": ("STRING", { - "multiline": False, - "default": "Group" - }), - "extrude": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01, "display": "number"}), - }, - } - - RETURN_TYPES = ("BPY_OBJS",) - RETURN_NAMES = ("bpy_objs",) - - FUNCTION = "process" - - CATEGORY = "mesh" - - def process(self, bpy_objs_target, name, extrude): - import global_bpy - bpy = global_bpy.get_bpy() - - if len(bpy_objs_target) == 0: - # throw error - return - - target_object = bpy_objs_target[0] - - # deselect all objects - bpy.ops.object.select_all(action='DESELECT') - # select only the target object - bpy.context.view_layer.objects.active = target_object - # enter enter edit mode and select all faces of the object to fill - bpy.ops.object.mode_set(mode='EDIT') - bpy.ops.mesh.select_all(action='SELECT') - - bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={ - "use_normal_flip": False, "use_dissolve_ortho_edges": False, "mirror": False}) - - bpy.ops.transform.resize( - value=(extrude, extrude, 1), constraint_axis=(False, False, False)) - - # remove the extruded vertex from the vertex group "name" - - bpy.ops.object.vertex_group_remove_from() - - # bpy.ops.mesh.delete(type='FACE') - bpy.ops.object.mode_set(mode='OBJECT') - - return ([target_object],) - - -NODE_CLASS_MAPPINGS = { - "CreateVertexBounds": CreateVertexBounds -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "CreateVertexBounds": "Vertex Bounds" -} diff --git a/blender/create_vertex_group.py b/blender/create_vertex_group.py deleted file mode 100644 index 78daa47..0000000 --- a/blender/create_vertex_group.py +++ /dev/null @@ -1,56 +0,0 @@ -class CreateVertexGroup(): - @classmethod - def INPUT_TYPES(s): - - return { - "required": { - "bpy_objs_target": ("BPY_OBJS",), - "name": ("STRING", { - "multiline": False, - "default": "Group" - }), - }, - } - - RETURN_TYPES = ("BPY_OBJS",) - RETURN_NAMES = ("bpy_objs",) - - FUNCTION = "process" - - CATEGORY = "mesh" - - def process(self, bpy_objs_target, name): - import global_bpy - bpy = global_bpy.get_bpy() - - if len(bpy_objs_target) == 0: - # throw error - return - - target_object = bpy_objs_target[0] - - # deselect all objects - bpy.ops.object.select_all(action='DESELECT') - # select only the target object - bpy.context.view_layer.objects.active = target_object - # enter enter edit mode and select all faces of the object to fill - bpy.ops.object.mode_set(mode='EDIT') - bpy.ops.mesh.select_all(action='SELECT') - - # create vertex group and assign all selected faces to it (the name of the vertex group is the same as the name of the object) - bpy.context.object.vertex_groups.new(name=name) - bpy.ops.object.vertex_group_assign() - - # bpy.ops.mesh.delete(type='FACE') - bpy.ops.object.mode_set(mode='OBJECT') - - return ([target_object],) - - -NODE_CLASS_MAPPINGS = { - "CreateVertexGroup": CreateVertexGroup -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "CreateVertexGroup": "Vertex Group (Old)" -} diff --git a/blender/disolve_faces.py b/blender/disolve_faces.py deleted file mode 100644 index a03886f..0000000 --- a/blender/disolve_faces.py +++ /dev/null @@ -1,61 +0,0 @@ -class DissolveFaces(): - @classmethod - def INPUT_TYPES(s): - - return { - "required": { - "bpy_objs_target": ("BPY_OBJS",), - "target_vertex_group": ("STRING", { - "multiline": False, - "default": "" - }), - }, - } - - RETURN_TYPES = ("BPY_OBJS",) - RETURN_NAMES = ("bpy_objs",) - - FUNCTION = "process" - - CATEGORY = "mesh" - - def process(self, bpy_objs_target, target_vertex_group): - import global_bpy - bpy = global_bpy.get_bpy() - - target_object = bpy_objs_target[0] - - # deselect all objects - bpy.ops.object.select_all(action='DESELECT') - # select only the target object - bpy.context.view_layer.objects.active = target_object - # enter enter edit mode and select all faces of the object to fill - bpy.ops.object.mode_set(mode='EDIT') - - bpy.ops.mesh.select_all(action='DESELECT') - - # if we have vertex group, select that instead - if target_vertex_group and target_vertex_group.strip() != "": - group = target_object.vertex_groups.get(target_vertex_group) - if group: - bpy.ops.object.vertex_group_set_active(group=group.name) - bpy.ops.object.vertex_group_select() - else: - bpy.ops.mesh.select_all(action='SELECT') - - # dissolve the faces - # bpy.ops.mesh.dissolve_faces() - bpy.ops.mesh.delete(type='ONLY_FACE') - # bpy.ops.mesh.delete(type='FACE') - bpy.ops.object.mode_set(mode='OBJECT') - - return ([target_object],) - - -NODE_CLASS_MAPPINGS = { - "DissolveFaces": DissolveFaces -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "DissolveFaces": "Dissolve Faces (Old)" -} diff --git a/blender/fill_face.py b/blender/fill_face.py deleted file mode 100644 index 3f77edd..0000000 --- a/blender/fill_face.py +++ /dev/null @@ -1,46 +0,0 @@ -class FillFace: - @classmethod - def INPUT_TYPES(s): - - return { - "required": { - "bpy_objs_target": ("BPY_OBJS",), - }, - } - - RETURN_TYPES = ("BPY_OBJS",) - RETURN_NAMES = ("bpy_objs",) - - FUNCTION = "process" - - CATEGORY = "mesh" - - def process(self, bpy_objs_target): - import global_bpy - bpy = global_bpy.get_bpy() - - target_object = bpy_objs_target[0] - - # deselect all objects - bpy.ops.object.select_all(action='DESELECT') - # select only the target object - bpy.context.view_layer.objects.active = target_object - # enter enter edit mode and select all faces of the object to fill - bpy.ops.object.mode_set(mode='EDIT') - bpy.ops.mesh.select_all(action='SELECT') - - # fill the faces - bpy.ops.mesh.fill() - - bpy.ops.object.mode_set(mode='OBJECT') - - return ([target_object],) - - -NODE_CLASS_MAPPINGS = { - "FillFace": FillFace -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "FillFace": "Fill Face (Old)" -} diff --git a/blender/group_object.py b/blender/group_object.py deleted file mode 100644 index 96e3cb7..0000000 --- a/blender/group_object.py +++ /dev/null @@ -1,30 +0,0 @@ -class GroupObject(): - @classmethod - def INPUT_TYPES(s): - - return { - "required": { - "bpy_objs_target": ("BPY_OBJS",), - "bpy_objs_target_2": ("BPY_OBJS",), - }, - } - - RETURN_TYPES = ("BPY_OBJS",) - RETURN_NAMES = ("bpy_objs",) - - FUNCTION = "process" - - CATEGORY = "mesh" - - def process(self, bpy_objs_target, bpy_objs_target_2): - combined_list = bpy_objs_target + bpy_objs_target_2 - return (combined_list,) - - -NODE_CLASS_MAPPINGS = { - "GroupObject": GroupObject -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "GroupObject": "Group Object" -} diff --git a/blender/group_vertex_inside.py b/blender/group_vertex_inside.py deleted file mode 100644 index 77e2c0e..0000000 --- a/blender/group_vertex_inside.py +++ /dev/null @@ -1,108 +0,0 @@ -class GroupVertexInside(): - @classmethod - def INPUT_TYPES(s): - - return { - "required": { - "bpy": ("BPY",), - "bpy_objs_target": ("BPY_OBJS",), - "name": ("STRING", { - "multiline": False, - "default": "Group" - }), - }, - } - - RETURN_TYPES = ("BPY_OBJS",) - RETURN_NAMES = ("bpy_objs",) - - FUNCTION = "process" - - CATEGORY = "mesh" - - def process(self, bpy_objs_target, name): - import global_bpy - bpy = global_bpy.get_bpy() - - target_object = bpy_objs_target[0] - - bpy.ops.object.mode_set(mode='OBJECT') - - # deselect all objects - bpy.ops.object.select_all(action='DESELECT') - # select only the target object - bpy.context.view_layer.objects.active = target_object - # enter enter edit mode and select all faces of the object to fill - bpy.ops.object.mode_set(mode='EDIT') - bpy.ops.mesh.select_all(action='DESELECT') - - # select the vetex group's vertices - bpy.ops.object.vertex_group_select() - - # get vertex group - vertex_group = target_object.vertex_groups[name] - - verts = target_object.data.vertices - - # all_vertices = [(v.co.x, v.co.y, i) for i, v in target_object.data.vertices] - - # get the verts in the group - verts_in_group = [v for v in verts if vertex_group.index in [vg.group for vg in v.groups]] - - # get all selected vertices's xy - # get the vertices of the vertex group - vertex_group_vertices = [(v.co.x, v.co.y) for v in verts_in_group] - - # get all vertices - # all_vertices = [(v.co.x, v.co.y) for v in target_object.data.vertices] - all_vertices_without_vertex_group = [(v.co.x, v.co.y, i) for i, v in enumerate(target_object.data.vertices) if v not in verts_in_group] - - from scipy.spatial import ConvexHull, Delaunay - - # create a convex hull of the vertex group's vertices - hull = ConvexHull(vertex_group_vertices) - - # create a Delaunay triangulation of the convex hull - tri = Delaunay(hull.points[hull.vertices]) - - # get the indices of the vertices that are inside the convex hull - inside_vertices_indices = [i for (x,y,i) in all_vertices_without_vertex_group if tri.find_simplex((x,y))>=0] - - # print(inside_vertices_indices) - # print(len(vertex_group_vertices)) - - bpy.ops.mesh.select_all(action='DESELECT') - - # select the vertices that are inside the convex hull - # for i in inside_vertices_indices: - # target_object.data.vertices[i].select = True - - # # select vertex from 1 to 10 - # for i in range(1, 100): - # target_object.data.vertices[i].select = True - - # create a new vertex group - # bpy.context.object.vertex_groups.new(name="fuck") - # bpy.ops.object.vertex_group_assign() - bpy.ops.object.mode_set(mode='OBJECT') - # create a new vertex group - # new_group = bpy.context.object.vertex_groups.new(name="new_group") - vertex_group.add(inside_vertices_indices, weight=1.0, type='REPLACE') - - # assign the selected vertices to the new vertex group - # new_group.add([v.index for v in target_object.data.vertices if v.select], weight=1.0, type='REPLACE') - # new_group.add([20, 100], weight=1.0, type='REPLACE') - # assign the selected vertices to the active vertex group - bpy.ops.object.mode_set(mode='OBJECT') - - - return ([target_object],) - - -NODE_CLASS_MAPPINGS = { - "GroupVertexInside": GroupVertexInside -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "GroupVertexInside": "Group Vertex Inside" -} diff --git a/blender/knift_project.py b/blender/knift_project.py deleted file mode 100644 index b778c27..0000000 --- a/blender/knift_project.py +++ /dev/null @@ -1,121 +0,0 @@ -class KnifeProjection: - @classmethod - def INPUT_TYPES(s): - - return { - "required": { - "bpy_objs_knife": ("BPY_OBJS",), - "bpy_objs_target": ("BPY_OBJS",), - }, - } - - RETURN_TYPES = ("BPY_OBJS",) - RETURN_NAMES = ("bpy_objs",) - - FUNCTION = "process" - - CATEGORY = "mesh" - - def process(self, bpy_objs_knife, bpy_objs_target): - import mathutils - import math - import global_bpy - bpy = global_bpy.get_bpy() - - knife_object = bpy_objs_knife[0] - target_object = bpy_objs_target[0] - - bpy.ops.object.select_all(action='DESELECT') - bpy.context.view_layer.objects.active = target_object - # knife_object.select_set(True) - # target_object.select_set(True) - - # bpy.ops.object.mode_set(mode='EDIT') - - area = next( - area for area in bpy.context.screen.areas if area.type == 'VIEW_3D') - space = next(space for space in area.spaces if space.type == 'VIEW_3D') - region = next( - region for region in area.regions if region.type == 'WINDOW') - - # space.region_3d.view_perspective = 'ORTHO' - # space.region_3d.view_rotation = mathutils.Euler( - # (0, 0, 0)).to_quaternion() - - # set blender to orthographic view without using numpad - - # bpy.ops.view3d.view_axis(type='TOP') - - override = bpy.context.copy() - - # override["active_object"] = target_object - # override["edit_object"] = target_object - # override["selected_objects"] = [knife_object, target_object] - # override["selected_editable_objects"] = [knife_object, target_object] - - override["region"] = region - override["area"] = area - override["space"] = space - - override["active_object"] = target_object - override["edit_object"] = target_object - override["selected_objects"] = [knife_object, target_object] - override["selected_editable_objects"] = [knife_object, target_object] - - knife_object.select_set(False) - target_object.select_set(True) - # move the kinfe object up a bit - bpy.ops.transform.translate(value=(0, 0, -0.1)) - bpy.ops.object.mode_set(mode='EDIT') - knife_object.select_set(False) - - # Get the viewport rotation - viewport_rotation = space.region_3d.view_rotation - - with bpy.context.temp_override(**override): - # # Create a rotation matrix representing a top-down view - # rotation_matrix = mathutils.Matrix.Rotation(math.radians(90.0), 4, 'X') - - # # Create a rotation matrix to make the object face the user - # rotation_matrix_face_user = mathutils.Matrix.Rotation(math.radians(180.0), 4, 'Z') - - # # Create a rotation matrix for the viewport rotation - # rotation_matrix_viewport = viewport_rotation.to_matrix().to_4x4() - - # # Remember the original locations - # original_location_knife = knife_object.location.copy() - # original_location_target = target_object.location.copy() - - # # Move the objects to the origin - # knife_object.location = mathutils.Vector((0, 0, 0)) - # target_object.location = mathutils.Vector((0, 0, 0)) - - # # Rotate the objects - # knife_object.matrix_world = rotation_matrix @ rotation_matrix_face_user @ rotation_matrix_viewport @ knife_object.matrix_world - # target_object.matrix_world = rotation_matrix @ rotation_matrix_face_user @ rotation_matrix_viewport @ target_object.matrix_world - - bpy.ops.view3d.view_axis(type='TOP', align_active=False) - bpy.ops.view3d.view_persportho() - bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1) - bpy.ops.mesh.knife_project() - - # # Rotate the objects back - # knife_object.matrix_world = rotation_matrix.inverted() @ knife_object.matrix_world - # target_object.matrix_world = rotation_matrix.inverted() @ target_object.matrix_world - - # # Move the objects back to their original locations - # knife_object.location = original_location_knife - # target_object.location = original_location_target - - bpy.ops.object.mode_set(mode='OBJECT') - - return ([target_object],) - - -NODE_CLASS_MAPPINGS = { - "KnifeProjection": KnifeProjection -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "KnifeProjection": "Knife Projection" -} diff --git a/blender/mesh_from_texture.py b/blender/mesh_from_texture.py deleted file mode 100644 index f5e2230..0000000 --- a/blender/mesh_from_texture.py +++ /dev/null @@ -1,104 +0,0 @@ -class MeshFromTexture: - def __init__(self): - pass - - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "image": ("IMAGE",), - # For disabling cache - "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), - }, - } - - RETURN_TYPES = ("IMAGE", "BPY_OBJS") - RETURN_NAMES = ("image", "bpy_objs") - - FUNCTION = "process" - - CATEGORY = "mesh" - - def process(self, image, seed): - import torch - import cv2 - import numpy as np - import global_bpy - bpy = global_bpy.get_bpy() - - image = np.copy(image[0].numpy()) - - gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) - gray = (gray * 255).astype(np.uint8) - - # Find contours - contours, _ = cv2.findContours( - gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) - - # Get the largest contour - areas = [cv2.contourArea(contour) for contour in contours] - - max_area_index = areas.index(max(areas)) - largest_contour = contours[max_area_index] - contours = [largest_contour] - - def normalize_vertices(vertices, max_value): - return vertices / float(max_value) * 2 - 1 - - # Get the image width and height - height, width = image.shape[:2] - - # Normalize the vertices - normalized_contours = [] - for contour in contours: - normalized_contour = [] - for vertex in contour: - normalized_vertex = [normalize_vertices( - vertex[0][0], width), normalize_vertices(vertex[0][1], height) * -1] - normalized_contour.append(normalized_vertex) - normalized_contours.append( - np.array(normalized_contour, dtype=np.float32)) - - meshes = [] - # print(len(normalized_contours)) - for i, contour in enumerate(normalized_contours): - # Create a new mesh for each contour - mesh = bpy.data.meshes.new(name=f"NewMesh{i}") - # Create a new object for each mesh - obj = bpy.data.objects.new(f"NewObject{i}", mesh) - # Link the object to the current collection - bpy.context.collection.objects.link(obj) - - # Add a z coordinate to each vertex - ordered_vertices = [(*vertex, 0) for vertex in contour] - # Create a face from the vertices - face = list(range(len(ordered_vertices))) - - # Create the mesh from the vertices and face - mesh.from_pydata(ordered_vertices, [], [face]) - - # Create a default shape key for the mesh - sk_basis = obj.shape_key_add(name='Basis') - - meshes.append(obj) # Add the object to the list of meshes - - # Draw contours on the original image - if not image.flags['C_CONTIGUOUS']: - image = np.ascontiguousarray(image) - cv2.drawContours(image, contours, -1, (0, 255, 0), 3) - - # Convert image back to tensor - image = [torch.from_numpy(image)] - return (image, meshes) - - -# A dictionary that contains all nodes you want to export with their names -# NOTE: names should be globally unique -NODE_CLASS_MAPPINGS = { - "MeshFromTexture": MeshFromTexture -} - -# A dictionary that contains the friendly/humanly readable titles for the nodes -NODE_DISPLAY_NAME_MAPPINGS = { - "MeshFromTexture": "Mesh from texture" -} diff --git a/blender/open_in_blender.py b/blender/open_in_blender.py deleted file mode 100644 index 390cc97..0000000 --- a/blender/open_in_blender.py +++ /dev/null @@ -1,48 +0,0 @@ -import subprocess -import folder_paths -import os -from mesh_utils import open_in_blender - - -class OpenInBlender: - def __init__(self): - self.my_blender_process = None - self.output_dir = folder_paths.get_output_directory() - - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "bpy_objs": ("BPY_OBJS",), - "blender_path": ("STRING", { - "multiline": False, - "default": "blender" - }), - "shading": (["Material", "Solid", "Rendered", "Wireframe"],), - "camera_location": ("VECTOR3D",), - "camera_rotation": ("VECTOR3D",), - }, - } - - RETURN_TYPES = () - FUNCTION = "process" - - OUTPUT_NODE = True - - CATEGORY = "mesh" - - def process(self, bpy_objs, blender_path, shading, camera_location, camera_rotation): - output_file = self.output_dir + '/tmp.blend' - p = open_in_blender(self.my_blender_process, blender_path=blender_path, output_file=output_file, camera_location=camera_location, - camera_rotation=camera_rotation, shading=shading) - self.my_blender_process = p - return {"ui": {}} - - -NODE_CLASS_MAPPINGS = { - "OpenInBlender": OpenInBlender -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "OpenInBlender": "Open in Blender" -} diff --git a/blender/plane.py b/blender/plane.py deleted file mode 100644 index f4f5b08..0000000 --- a/blender/plane.py +++ /dev/null @@ -1,74 +0,0 @@ -class Plane: - @classmethod - def INPUT_TYPES(s): - - return { - "required": { - "division": ("INT", { - "default": 0, - "min": 0, - "max": 256, - "step": 1, - "display": "number" - }), - "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), # For disabling cache - }, - } - - RETURN_TYPES = ("BPY_OBJS",) - RETURN_NAMES = ("bpy_objs",) - - FUNCTION = "process" - - CATEGORY = "mesh" - - def process(self, division, seed): - import global_bpy - bpy = global_bpy.get_bpy() - - # Define coordinates for the plane to object mode - if bpy.context.active_object is not None: - bpy.ops.object.mode_set(mode='OBJECT') - coords = [(-1, -1, 0), (1, -1, 0), (-1, 1, 0), (1, 1, 0)] - - # Create a mesh object - mesh = bpy.data.meshes.new(name="PlaneMesh") - mesh.from_pydata(coords,[],[(0,1,3,2)]) - - # Create a new object with the mesh - object_a = bpy.data.objects.new(name="PlaneObject", object_data=mesh) - bpy.ops.object.select_all(action='DESELECT') - bpy.context.collection.objects.link(object_a) - bpy.context.view_layer.objects.active = object_a - object_a.select_set(True) - - # Invert the Y axis of the UV to fix the vertical inversion - bpy.ops.transform.resize(value=(-1, -1, 1)) - - # Create a new UV map - uv_map = mesh.uv_layers.new(name="newUV") - mesh.uv_layers.active = uv_map - - # Unwrap the mesh - bpy.ops.object.mode_set(mode='EDIT') - bpy.ops.uv.unwrap() - bpy.ops.object.mode_set(mode='OBJECT') - - # Subdivide the plane - if division > 0: - original_mode = bpy.context.object.mode - bpy.ops.object.mode_set(mode='EDIT') - bpy.ops.mesh.subdivide(number_cuts=division) - bpy.ops.object.mode_set(mode=original_mode) - - sk_basis = object_a.shape_key_add(name='Basis') - - return ([object_a],) - -NODE_CLASS_MAPPINGS = { - "Plane": Plane -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "Plane": "Plane (Old)" -} diff --git a/blender/scale_vertex.py b/blender/scale_vertex.py deleted file mode 100644 index 65ca027..0000000 --- a/blender/scale_vertex.py +++ /dev/null @@ -1,55 +0,0 @@ -class ScaleVertex(): - @classmethod - def INPUT_TYPES(s): - - return { - "required": { - "bpy_objs_target": ("BPY_OBJS",), - "extrude": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01, "display": "number"}), - }, - } - - RETURN_TYPES = ("BPY_OBJS",) - RETURN_NAMES = ("bpy_objs",) - - FUNCTION = "process" - - CATEGORY = "mesh" - - def process(self, bpy_objs_target, extrude): - import global_bpy - bpy = global_bpy.get_bpy() - - if len(bpy_objs_target) == 0: - # throw error - return - - target_object = bpy_objs_target[0] - - # deselect all objects - bpy.ops.object.select_all(action='DESELECT') - # select only the target object - bpy.context.view_layer.objects.active = target_object - # enter enter edit mode and select all faces of the object to fill - bpy.ops.object.mode_set(mode='EDIT') - bpy.ops.mesh.select_all(action='SELECT') - - bpy.ops.transform.resize( - value=(extrude, extrude, 1), constraint_axis=(False, False, False)) - - # remove the extruded vertex from the vertex group "name" - # bpy.ops.object.vertex_group_remove_from() - - # bpy.ops.mesh.delete(type='FACE') - bpy.ops.object.mode_set(mode='OBJECT') - - return ([target_object],) - - -NODE_CLASS_MAPPINGS = { - "ScaleVertex": ScaleVertex -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "ScaleVertex": "Scale Vertex" -} diff --git a/blender/texture.py b/blender/texture.py deleted file mode 100644 index 26d80d1..0000000 --- a/blender/texture.py +++ /dev/null @@ -1,92 +0,0 @@ -class Texture: - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "bpy_objs": ("BPY_OBJS",), - "texture": ("IMAGE",), - "texture_name": ("STRING", { - "multiline": False, - "default": "my_image" - }), - }, - } - - RETURN_TYPES = ("BPY_OBJS",) - RETURN_NAMES = ("bpy_objs",) - - FUNCTION = "process" - - # OUTPUT_NODE = False - - CATEGORY = "mesh" - - def process(self, bpy_objs, texture, texture_name): - import numpy as np - import global_bpy - bpy = global_bpy.get_bpy() - - # Convert image to numpy - texture = texture[0].numpy() - - # Flip the image vertically - texture = np.flipud(texture) - - # Create an image with the required dimensions - img = bpy.data.images.new(texture_name, width=texture.shape[1], height=texture.shape[0]) - - # If there is no alpha channel, append one full of 1's - if texture.shape[2] == 3: - alpha_channel = np.ones((*texture.shape[:2], 1)) - texture = np.concatenate((texture, alpha_channel), axis=2) - - # Flatten image data and rearrange color channels for blender - img.pixels = texture.ravel() - - # Pack image to store it within .blend file - img.pack() - - # Save image to a file - # img.filepath_raw = 'test.png' - # img.file_format = 'PNG' - # img.save() - - # Get the active object - obj = bpy_objs[0] - - # Create a material - mat = bpy.data.materials.new("MaterialName") - mat.use_nodes = True - nodes = mat.node_tree.nodes - for node in nodes: - nodes.remove(node) - - # Add a new texture node - texture_node = nodes.new(type='ShaderNodeTexImage') - texture_node.image = img - - # Add a new BSDF node - bsdf_node = nodes.new(type='ShaderNodeBsdfPrincipled') - - # Add a new output node - output_node = nodes.new(type='ShaderNodeOutputMaterial') - - # Link nodes together - links = mat.node_tree.links - links.new(bsdf_node.inputs['Base Color'], texture_node.outputs['Color']) - links.new(output_node.inputs['Surface'], bsdf_node.outputs['BSDF']) - - # Assign the material to the active object - if obj.data.materials: - obj.data.materials[0] = mat - else: - obj.data.materials.append(mat) - return (bpy_objs,) - -NODE_CLASS_MAPPINGS = { - "Texture": Texture -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "Texture": "Texture" -} diff --git a/blender/transform_object.py b/blender/transform_object.py deleted file mode 100644 index 6b8d3f4..0000000 --- a/blender/transform_object.py +++ /dev/null @@ -1,45 +0,0 @@ -class TransfromObject(): - @classmethod - def INPUT_TYPES(s): - - return { - "required": { - "bpy_objs_target": ("BPY_OBJS",), - "x": ("FLOAT", {"default": 0.0, "min": -10.0, "max": 10.0, "step": 0.01, "display": "number"}), - "y": ("FLOAT", {"default": 0.0, "min": -10.0, "max": 10.0, "step": 0.01, "display": "number"}), - "z": ("FLOAT", {"default": 0.0, "min": -10.0, "max": 10.0, "step": 0.01, "display": "number"}), - - }, - } - - RETURN_TYPES = ("BPY_OBJS",) - RETURN_NAMES = ("bpy_objs",) - - FUNCTION = "process" - - CATEGORY = "mesh" - - def process(self, bpy_objs_target, x, y, z): - import global_bpy - bpy = global_bpy.get_bpy() - - target_object = bpy_objs_target[0] - - bpy.ops.object.select_all(action='DESELECT') - bpy.context.view_layer.objects.active = target_object - - # move the object in level transformation - target_object.location.x += x - target_object.location.y += y - target_object.location.z += z - - return ([target_object],) - - -NODE_CLASS_MAPPINGS = { - "TransfromObject": TransfromObject -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "TransfromObject": "Transfrom Object" -} diff --git a/common/point_visualizer.py b/common/point_visualizer.py deleted file mode 100644 index e46f03a..0000000 --- a/common/point_visualizer.py +++ /dev/null @@ -1,52 +0,0 @@ -import torch -from einops import rearrange -from nodes import PreviewImage - -class PointVisualizer(PreviewImage): - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "images": ("IMAGE",), - "point": ("VECTOR3D",), - "point_size": ("INT", { - "default": 1, - "min": 10, - "max": 20, - "step": 1, - "display": "number" - }), - }, - } - - FUNCTION = "process" - - CATEGORY = "image" - - def process(self, images, point, point_size): - x, y, z = point - h, w, c = images[0].shape - point_image = torch.zeros(images[0].shape) - - center_x, center_y, _ = point - top_left_x = center_x - point_size // 2 - top_left_y = center_y - point_size // 2 - - # Make sure the square is within the image boundaries - top_left_x = max(0, min(w - point_size, top_left_x)) - top_left_y = max(0, min(h - point_size, top_left_y)) - - point_image[top_left_y:top_left_y+point_size, top_left_x:top_left_x+point_size] = 1 - point_image = rearrange(point_image, 'h w c -> 1 h w c') - - # Blending - images = images * 0.2 + point_image * 0.8 - return self.save_images(images) - -NODE_CLASS_MAPPINGS = { - "PointVisualizer": PointVisualizer -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "PointVisualizer": "Point Visualizer" -} diff --git a/common/vector3d.py b/common/vector3d.py deleted file mode 100644 index 0aa45e1..0000000 --- a/common/vector3d.py +++ /dev/null @@ -1,45 +0,0 @@ -class VECTOR3D: - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "x": ("INT", { - "default": 0, - "min": -1024, - "max": 1024, - "step": 1, - "display": "number" - }), - "y": ("INT", { - "default": 0, - "min": -1024, - "max": 1024, - "step": 1, - "display": "number" - }), - "z": ("INT", { - "default": 0, - "min": -1024, - "max": 1024, - "step": 1, - "display": "number" - }), - }, - } - - RETURN_TYPES = ("VECTOR3D",) - - FUNCTION = "run" - - CATEGORY = "utils" - - def run(self, x, y, z): - return ([x, y, z],) - -NODE_CLASS_MAPPINGS = { - "VECTOR3D": VECTOR3D -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "VECTOR3D": "Vector 3D" -} diff --git a/sam/avatar_segmentation.py b/sam/avatar_segmentation.py deleted file mode 100644 index b9964df..0000000 --- a/sam/avatar_segmentation.py +++ /dev/null @@ -1,67 +0,0 @@ -import torch -from einops import rearrange, repeat -from torchvision import transforms -from PIL import Image -import numpy as np -import cv2 -import base64 -import requests -import json -import io - -class AvatarSegmentation: - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "image": ("IMAGE",), - } - } - - RETURN_TYPES = ("IMAGE", "IMAGE", "IMAGE", "IMAGE", "IMAGE") - RETURN_NAMES = ("back_hair", "front_hair","eyes", "eyelashes", "mouth") - - FUNCTION = "segment" - - CATEGORY = "image" - - def segment(self, image): - # Convert tensor to PIL image - image = image[0] - image = rearrange(image, 'h w c -> c h w') - image = transforms.ToPILImage()(image) - - # Save image to in-memory file - image_buff = io.BytesIO() - image.save(image_buff, format="PNG") - image_string = base64.b64encode(image_buff.getvalue()).decode("utf-8") - - # Send request to API - url = 'https://q41iq6s6t8.execute-api.ap-southeast-1.amazonaws.com/seg-cpu' - headers = { - 'content-type': 'application/json' - } - data = { - 'img_str': image_string - } - response = requests.post(url, headers=headers, data=json.dumps(data)) - - # Convert response to tensors - outs = [] - masks = response.json() - for segment_name, img_str in masks.items(): - mask = base64.b64decode(img_str.encode('utf-8')) - mask = Image.open(io.BytesIO(mask)) - mask = np.array(mask) - mask = torch.from_numpy(mask) # shape: H, W, 3 - mask = rearrange(mask, 'h w c -> 1 h w c') - outs.append(mask) - return outs - -NODE_CLASS_MAPPINGS = { - "AvatarSegmentation": AvatarSegmentation -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "AvatarSegmentation": "Avatar Segmentation" -} diff --git a/sam/sam_load_emb.py b/sam/sam_load_emb.py deleted file mode 100644 index 05f4453..0000000 --- a/sam/sam_load_emb.py +++ /dev/null @@ -1,52 +0,0 @@ -import folder_paths -import torch -from segment_anything import SamAutomaticMaskGenerator, sam_model_registry -from einops import rearrange, repeat - - -class SAM_Load_Embedding: - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "filename": ("STRING", { - "multiline": False, - "default": "embeddings" - }), - "embedding_id": ("STRING", { - "multiline": False, - "default": "embedding" - }), - } - } - - RETURN_TYPES = ("EMBEDDINGS",) - RETURN_NAMES = ("EMBEDDINGS",) - - OUTPUT_NODE = True - - FUNCTION = "process" - - CATEGORY = "image" - - def process(self, filename, embedding_id): - import json - import numpy as np - - data = {} - with open(filename, 'r') as f: - data = json.load(f) - - # Convert list to numpy ndarray - data['image_embedding'] = np.array(data['image_embedding']) - - return (data, ) - - -NODE_CLASS_MAPPINGS = { - "SAM_Load_Embedding": SAM_Load_Embedding -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "SAM_Load_Embedding": "SAM_Load_Embedding " -} diff --git a/sam/sam_loader.py b/sam/sam_loader.py deleted file mode 100644 index 3a4eef7..0000000 --- a/sam/sam_loader.py +++ /dev/null @@ -1,42 +0,0 @@ -import folder_paths -import torch -from segment_anything import SamAutomaticMaskGenerator, sam_model_registry -from einops import rearrange, repeat -import requests -from PIL import Image -import io -import numpy as np -from segment_anything import SamAutomaticMaskGenerator, sam_model_registry, SamPredictor -from einops import rearrange, repeat - -class SAM_Remote_Emb: - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "model_type": (["vit_h", "vit_l", "vit_b"],), - "ckpt": (folder_paths.get_filename_list("sams"),), - }, - } - - RETURN_TYPES = ("SAM", "SAMPREDICTOR") - RETURN_NAMES = ("sam", "predictor") - - FUNCTION = "segment" - - CATEGORY = "image" - - def segment(self, model_type, ckpt): - ckpt = folder_paths.get_full_path("sams", ckpt) - sam = sam_model_registry[model_type](checkpoint=ckpt) - predictor = SamPredictor(sam) - - return (sam, predictor) - -NODE_CLASS_MAPPINGS = { - "SAM_Loader": SAM_Remote_Emb -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "SAM_Loader": "SAM Loader" -} diff --git a/sam/sam_node_from_emb.py b/sam/sam_node_from_emb.py deleted file mode 100644 index abf914a..0000000 --- a/sam/sam_node_from_emb.py +++ /dev/null @@ -1,110 +0,0 @@ -import torch -from einops import rearrange, repeat -import numpy as np -import cv2 - -class SAM_Predict: - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "image": ("IMAGE",), - "embeddings": ("EMBEDDINGS",), - "predictor": ("SAMPREDICTOR",), - }, - "optional": { - "prompt": ("SAM_PROMPT", ), - "mask": ("IMAGE",), - } - } - - RETURN_TYPES = ("IMAGE","IMAGE", "IMAGE") - RETURN_NAMES = ("image","out_image", "mask") - - FUNCTION = "segment" - - CATEGORY = "image" - - def segment(self, image, embeddings, predictor, prompt, mask=None): - image_embedding_list = embeddings['image_embedding'] - shape = tuple(embeddings['shape']) - input_size = tuple(embeddings['input_size']) - - # Convert the list back to a numpy array with the original shape - image_embedding_np = np.array(image_embedding_list, dtype=np.single).reshape(shape) - - # Convert the numpy array to a PyTorch tensor - image_embedding_tensor = torch.from_numpy(image_embedding_np) - - # Set the image embeddings for the model - # predictor.set_torch_image(image_embedding_tensor, image.shape[:2]) - # print(image[0].shape[:2]) - predictor.input_size = input_size - predictor.features = image_embedding_tensor - predictor.is_image_set = True - predictor.original_size = image[0].shape[:2] - - # prompt = [{"x":364,"y":153,"label":1},{"x":296,"y":189,"label":1},{"x":277,"y":246,"label":1}] - - # if point_1 != None: - # x, y, z = point_1 - - # point_coords = np.array([[x, y]]) - # point_labels = np.array([1]) - - if prompt == None or len(prompt) == 0: - return (image, image, None) - - point_coords = np.array([[p['x'], p['y']] for p in prompt]) - point_labels = np.array([p['label'] for p in prompt]) - - masks, iou_predictions, low_res_masks = predictor.predict( - point_coords=point_coords, - point_labels=point_labels, - ) - - if mask != None: - # scale the mask to 256x256 - cv2_mask = cv2.resize(np.array(mask[0]), (256, 256)) - cv2_mask = cv2_mask[np.newaxis, :, :] - cv2_mask = (cv2_mask * 255).astype(int) - - true_locations = np.array(np.where(cv2_mask[0] == 255)) - if true_locations.shape[1] > 0: - # Randomly select a point in the mask - rand_index = np.random.randint(true_locations.shape[1]) - y, x = true_locations[:, rand_index] - point_coords = np.array([[x, y]]) - point_labels = np.array([1]) - - masks, iou_predictions, low_res_masks = predictor.predict( - point_coords=point_coords, - point_labels=point_labels, - mask_input=cv2_mask - ) - else: - # No detected mask - h, w, c = image[0].shape - masks = np.zeros((1, h, w)) - - masks = torch.from_numpy(masks) - - masks = rearrange(masks[0], 'h w -> 1 h w') - # masks = rearrange(masks, 'c h w -> 1 c h w') - out_image = repeat(masks, '1 h w -> 1 h w c', c=3) * image - - print(masks.shape, torch.max(masks), torch.min(masks)) - print(image.shape, torch.max(image), torch.min(image)) - - # print(emb) - - # print(masks, out_image) - return (image, out_image, masks) - -NODE_CLASS_MAPPINGS = { - "SAM_Predict": SAM_Predict -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "SAM_Predict": "SAM Predict" -} diff --git a/sam/sam_node_remote.py b/sam/sam_node_remote.py deleted file mode 100644 index c68e2a4..0000000 --- a/sam/sam_node_remote.py +++ /dev/null @@ -1,88 +0,0 @@ -import requests -from PIL import Image -import io -import numpy as np -import folder_paths - -class SAM_Embedding: - def __init__(self): - self.output_dir = folder_paths.get_output_directory() - - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "image": ("IMAGE",), - "embedding_id": ("STRING", { - "multiline": False, - "default": "embedding" - }), - }, - "optional": { - "predictor": ("SAMPREDICTOR",) - } - } - - RETURN_TYPES = ("EMBEDDINGS", ) - RETURN_NAMES = ("embeddings", ) - - FUNCTION = "segment" - - CATEGORY = "image" - - def segment(self, image, embedding_id, predictor=None): - # Convert PyTorch tensor to numpy array - image_np = (image[0].numpy() * 255).astype(np.uint8) - - if predictor != None: - predictor.set_image(image_np) - emb = predictor.get_image_embedding().cpu().numpy() - output = { - "image_embedding": emb, - "shape": emb.shape, - "input_size": predictor.input_size - } - else: - # Convert numpy array to PIL Image - img = Image.fromarray(image_np) - - # Create an in-memory bytes buffer - img_byte_arr = io.BytesIO() - - # Save the PIL Image to the bytes buffer in PNG format - img.save(img_byte_arr, format='PNG') - - # Get the bytes value of the buffer - img_byte_arr = img_byte_arr.getvalue() - - # Create a dictionary with the image bytes - files = {'image': ('image.png', img_byte_arr)} - - # Send the POST request - response = requests.post('https://avatechgg--segment-anything-entrypoint.modal.run', files=files) - - # Check if the request was successful - if response.status_code == 200: - # Parse the JSON response - output = response.json() - else: - print(f"Request failed with status code {response.status_code}") - output = None - - # sam = sam_model_registry[model_type](checkpoint=ckpt) - # predictor = SamPredictor(sam) - # masks = predictor.set_torch_image - # masks = predictor.predict - - # print(output) - - np.save(f"{self.output_dir}/{embedding_id}.npy", output["image_embedding"]) - return (output, ) - -NODE_CLASS_MAPPINGS = { - "SAM_Embedding": SAM_Embedding -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "SAM_Embedding": "SAM Embedding" -} diff --git a/sam/sam_prompt.py b/sam/sam_prompt.py deleted file mode 100644 index 81598aa..0000000 --- a/sam/sam_prompt.py +++ /dev/null @@ -1,68 +0,0 @@ -import folder_paths -import os -import numpy as np -import re -from segment_anything import sam_model_registry, SamPredictor - - -class SAM_Prompt_Image: - def __init__(self): - self.output_dir = folder_paths.get_output_directory() - - @classmethod - def INPUT_TYPES(s): - input_dir = folder_paths.get_input_directory() - files = [ - f - for f in os.listdir(input_dir) - if os.path.isfile(os.path.join(input_dir, f)) - ] - return { - "required": { - "image": ("IMAGE",), - "ckpt": (folder_paths.get_filename_list("sams"),), - "embedding_id": ( - "STRING", - {"multiline": False, "default": "embedding"}, - ), - # "image": (sorted(files), ), - "image_prompts_json": ("STRING", {"multiline": False, "default": "[]"}), - }, - } - - CATEGORY = "image" - - RETURN_TYPES = ("SAM_PROMPT",) - FUNCTION = "load_image" - - def load_image(self, image, ckpt, embedding_id, image_prompts_json): - import json - - emb_filename = f"{self.output_dir}/{embedding_id}.npy" - if not os.path.exists(emb_filename): - ckpt = folder_paths.get_full_path("sams", ckpt) - model_type = re.findall(r'vit_[lbh]', ckpt)[0] - sam = sam_model_registry[model_type](checkpoint=ckpt) - predictor = SamPredictor(sam) - - image_np = (image[0].numpy() * 255).astype(np.uint8) - predictor.set_image(image_np) - emb = predictor.get_image_embedding().cpu().numpy() - np.save(emb_filename, emb) - - image_prompts = json.loads(image_prompts_json) - - result = (image_prompts,) - - if isinstance(image_prompts, list): - pass - elif all(isinstance(item, list) for item in image_prompts.values()): - for item in image_prompts.values(): - result += (item,) - - return result - - -NODE_CLASS_MAPPINGS = {"SAM_Prompt_Image": SAM_Prompt_Image} - -NODE_DISPLAY_NAME_MAPPINGS = {"SAM_Prompt_Image": "SAM_Prompt_Image "} diff --git a/sam/sam_save_emb.py b/sam/sam_save_emb.py deleted file mode 100644 index 6b6943e..0000000 --- a/sam/sam_save_emb.py +++ /dev/null @@ -1,64 +0,0 @@ -import folder_paths -import torch -import os -from segment_anything import SamAutomaticMaskGenerator, sam_model_registry -from einops import rearrange, repeat - -class SAM_Save_Embedding: - def __init__(self): - self.output_dir = folder_paths.get_output_directory() - self.type = "output" - self.prefix_append = "" - - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "embeddings": ("EMBEDDINGS",), - "filename": ("STRING", { - "multiline": False, - "default": "embeddings" - }), - "write_mode": (["Overwrite", "Increment"],), - } - } - - RETURN_TYPES = () - RETURN_NAMES = () - - OUTPUT_NODE = True - - FUNCTION = "process" - - CATEGORY = "image" - - def process(self, embeddings, filename, write_mode): - import json - import numpy as np - - filepath = self.output_dir + "/" + filename + '.json' - - if write_mode == "Increment": - count = 0 - # while file exists, increment count - while os.path.exists(self.output_dir + "/" + filename + '_' + str(count) + '.json'): - count += 1 - - filepath = self.output_dir + "/" + filename + '_' + str(count) + '.json' - - # print(embeddings) - if isinstance(embeddings['image_embedding'], np.ndarray): - embeddings['image_embedding'] = embeddings['image_embedding'].tolist() - with open(filepath, 'w') as f: - json.dump(embeddings, f) - - return { "ui" : { "file": { filepath.replace(f"{self.output_dir}/", "") } } } - - -NODE_CLASS_MAPPINGS = { - "SAM_Save_Embedding": SAM_Save_Embedding -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "SAM_Save_Embedding": "SAM_Save_Embedding " -}