diff --git a/addon.py b/addon.py index 1b14c29..fc075fb 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: + pass + 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..460de59 100644 --- a/src/blender_mcp/server.py +++ b/src/blender_mcp/server.py @@ -11,6 +11,7 @@ import os from pathlib import Path import base64 from urllib.parse import urlparse +import math # Configure logging logging.basicConfig(level=logging.INFO, @@ -691,6 +692,9 @@ 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] | None) -> list[int] | None: + 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 +708,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 +717,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: @@ -743,7 +747,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 +774,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 +902,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