"""
Selection tools for retopology workflows.
Provides safe, parameterized tools for selecting problematic geometry.
"""
from typing import Dict, Any
from mcp.server.fastmcp import Context
import logging
logger = logging.getLogger("BlenderMCPServer")
# ============================================================================
# SELECT NON-MANIFOLD
# ============================================================================
def select_non_manifold(
ctx: Context,
blender_connection,
wire: bool = True,
boundaries: bool = True,
multiple_faces: bool = True,
non_contiguous: bool = True
) -> str:
"""
Select non-manifold mesh elements for topology validation.
Selects problematic geometry that may cause issues in remeshing operations.
Non-manifold geometry includes edges with more than 2 faces, edges with
only 1 face (boundaries), wire edges, and non-contiguous vertices.
Requires Edit Mode.
Parameters:
- wire: Select wire edges (edges with no faces) (default: true)
- boundaries: Select boundary edges (edges with 1 face) (default: true)
- multiple_faces: Select edges with 3+ faces (default: true)
- non_contiguous: Select vertices connecting disjoint geometry (default: true)
Returns status message with count of selected elements.
"""
try:
result = blender_connection.send_command("select_non_manifold", {
"wire": wire,
"boundaries": boundaries,
"multiple_faces": multiple_faces,
"non_contiguous": non_contiguous
})
if "error" in result:
return f"Error: {result['error']}"
output = "Non-Manifold Selection Complete!\n\n"
output += "Selection Criteria:\n"
output += f" - Wire Edges: {wire}\n"
output += f" - Boundary Edges: {boundaries}\n"
output += f" - Multiple Face Edges: {multiple_faces}\n"
output += f" - Non-Contiguous Vertices: {non_contiguous}\n\n"
if 'vertices_selected' in result:
output += f"Vertices Selected: {result['vertices_selected']}\n"
if 'edges_selected' in result:
output += f"Edges Selected: {result['edges_selected']}\n"
if result.get('vertices_selected', 0) == 0 and result.get('edges_selected', 0) == 0:
output += "\n✓ No non-manifold geometry found! Mesh is clean.\n"
else:
output += "\n⚠ Non-manifold geometry found. Consider fixing before remeshing.\n"
return output
except Exception as e:
logger.error(f"Error selecting non-manifold: {str(e)}")
return f"Error selecting non-manifold: {str(e)}"