diff --git a/addon.py b/addon.py index 1b14c29..7738ac1 100644 --- a/addon.py +++ b/addon.py @@ -1415,6 +1415,9 @@ class BlenderMCPServer: @staticmethod def _clean_imported_glb(filepath, mesh_name=None): + # Get the set of existing objects before import + existing_objects = set(bpy.data.objects) + # Import the GLB file bpy.ops.import_scene.gltf(filepath=filepath) @@ -1422,7 +1425,8 @@ class BlenderMCPServer: bpy.context.view_layer.update() # Get all imported objects - imported_objects = [obj for obj in bpy.context.view_layer.objects if obj.select_get()] + imported_objects = list(set(bpy.data.objects) - existing_objects) + # imported_objects = [obj for obj in bpy.context.view_layer.objects if obj.select_get()] if not imported_objects: print("Error: No objects were imported.") @@ -1457,10 +1461,15 @@ class BlenderMCPServer: return # Rename the mesh if needed - if mesh_obj and mesh_name: - mesh_obj.name = mesh_name - print(f"Mesh renamed to: {mesh_name}") - + try: + if mesh_obj and mesh_obj.name is not None and mesh_name: + mesh_obj.name = mesh_name + if mesh_obj.data.name is not None: + mesh_obj.data.name = mesh_name + print(f"Mesh renamed to: {mesh_name}") + except Exception as e: + print("Having issue with renaming, give up renaming.") + return mesh_obj def import_generated_asset(self, *args, **kwargs): diff --git a/src/blender_mcp/server.py b/src/blender_mcp/server.py index 16a0f04..09f7954 100644 --- a/src/blender_mcp/server.py +++ b/src/blender_mcp/server.py @@ -691,6 +691,15 @@ def get_hyper3d_status(ctx: Context) -> str: logger.error(f"Error checking Hyper3D status: {str(e)}") return f"Error checking Hyper3D status: {str(e)}" +def _process_bbox(original_bbox: list[float] | list[int] | None) -> list[int] | None: + if original_bbox is None: + return None + if all(isinstance(i, int) for i in original_bbox): + return original_bbox + if any(i<=0 for i in original_bbox): + raise ValueError("Incorrect number range: bbox must be bigger than zero!") + return [int(float(i) / max(original_bbox) * 100) for i in original_bbox] if original_bbox else None + @mcp.tool() def generate_hyper3d_model_via_text( ctx: Context, @@ -704,7 +713,7 @@ def generate_hyper3d_model_via_text( Parameters: - text_prompt: A short description of the desired model in **English**. - - bbox_condition: Optional. If given, it has to be a list of floats of length 3. Controls the ratio between [Length, Width, Height] of the model. The final size of the model is normalized. + - bbox_condition: Optional. If given, it has to be a list of floats of length 3. Controls the ratio between [Length, Width, Height] of the model. Returns a message indicating success or failure. """ @@ -713,7 +722,7 @@ def generate_hyper3d_model_via_text( result = blender.send_command("create_rodin_job", { "text_prompt": text_prompt, "images": None, - "bbox_condition": bbox_condition, + "bbox_condition": _process_bbox(bbox_condition), }) succeed = result.get("submit_time", False) if succeed: @@ -726,7 +735,6 @@ def generate_hyper3d_model_via_text( except Exception as e: logger.error(f"Error generating Hyper3D task: {str(e)}") return f"Error generating Hyper3D task: {str(e)}" - return f"Placeholder, under development, not implemented yet." @mcp.tool() def generate_hyper3d_model_via_images( @@ -743,7 +751,7 @@ def generate_hyper3d_model_via_images( Parameters: - input_image_paths: The **absolute** paths of input images. Even if only one image is provided, wrap it into a list. Required if Hyper3D Rodin in MAIN_SITE mode. - input_image_urls: The URLs of input images. Even if only one image is provided, wrap it into a list. Required if Hyper3D Rodin in FAL_AI mode. - - bbox_condition: Optional. If given, it has to be a list of ints of length 3. Controls the ratio between [Length, Width, Height] of the model. The final size of the model is normalized. + - bbox_condition: Optional. If given, it has to be a list of ints of length 3. Controls the ratio between [Length, Width, Height] of the model. Only one of {input_image_paths, input_image_urls} should be given at a time, depending on the Hyper3D Rodin's current mode. Returns a message indicating success or failure. @@ -770,7 +778,7 @@ def generate_hyper3d_model_via_images( result = blender.send_command("create_rodin_job", { "text_prompt": None, "images": images, - "bbox_condition": bbox_condition, + "bbox_condition": _process_bbox(bbox_condition), }) succeed = result.get("submit_time", False) if succeed: @@ -898,7 +906,7 @@ def asset_creation_strategy() -> str: Adjust the imported mesh's location, scale, rotation, so that the mesh is on the right spot. You can reuse assets previous generated by running python code to duplicate the object, without creating another generation task. - + 2. If all integrations are disabled or when falling back to basic tools: - create_object() for basic primitives (CUBE, SPHERE, CYLINDER, etc.) - set_material() for basic colors and materials