kicad-mcp/kicad_mcp/tools/model3d_tools.py
Ryan Malloy bc0f3db97c
Some checks are pending
CI / Lint and Format (push) Waiting to run
CI / Test Python 3.11 on macos-latest (push) Waiting to run
CI / Test Python 3.12 on macos-latest (push) Waiting to run
CI / Test Python 3.13 on macos-latest (push) Waiting to run
CI / Test Python 3.10 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.11 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.12 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.13 on ubuntu-latest (push) Waiting to run
CI / Security Scan (push) Waiting to run
CI / Build Package (push) Blocked by required conditions
Implement comprehensive AI/LLM integration for KiCad MCP server
Add intelligent analysis and recommendation tools for KiCad designs:

## New AI Tools (kicad_mcp/tools/ai_tools.py)
- suggest_components_for_circuit: Smart component suggestions based on circuit analysis
- recommend_design_rules: Automated design rule recommendations for different technologies
- optimize_pcb_layout: PCB layout optimization for signal integrity, thermal, and cost
- analyze_design_completeness: Comprehensive design completeness analysis

## Enhanced Utilities
- component_utils.py: Add ComponentType enum and component classification functions
- pattern_recognition.py: Enhanced circuit pattern analysis and recommendations
- netlist_parser.py: Implement missing parse_netlist_file function for AI tools

## Key Features
- Circuit pattern recognition for power supplies, amplifiers, microcontrollers
- Technology-specific design rules (standard, HDI, RF, automotive)
- Layout optimization suggestions with implementation steps
- Component suggestion system with standard values and examples
- Design completeness scoring with actionable recommendations

## Server Integration
- Register AI tools in FastMCP server
- Integrate with existing KiCad utilities and file parsers
- Error handling and graceful fallbacks for missing data

Fixes ImportError that prevented server startup and enables advanced
AI-powered design assistance for KiCad projects.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-11 16:15:58 -06:00

336 lines
13 KiB
Python

"""
3D Model Analysis Tools for KiCad MCP Server.
Provides MCP tools for analyzing 3D models, mechanical constraints,
and visualization data from KiCad PCB files.
"""
import json
from typing import Any
from fastmcp import FastMCP
from kicad_mcp.utils.model3d_analyzer import (
Model3DAnalyzer,
analyze_pcb_3d_models,
get_mechanical_constraints,
)
from kicad_mcp.utils.path_validator import validate_kicad_file
def register_model3d_tools(mcp: FastMCP) -> None:
"""Register 3D model analysis tools with the MCP server."""
@mcp.tool()
def analyze_3d_models(pcb_file_path: str) -> dict[str, Any]:
"""
Analyze 3D models and mechanical aspects of a KiCad PCB file.
Extracts 3D component information, board dimensions, clearance violations,
and generates data suitable for 3D visualization.
Args:
pcb_file_path: Full path to the .kicad_pcb file to analyze
Returns:
Dictionary containing 3D analysis results including:
- board_dimensions: Physical board size and outline
- components: List of 3D components with positions and models
- height_analysis: Component height statistics
- clearance_violations: Detected mechanical issues
- stats: Summary statistics
Examples:
analyze_3d_models("/path/to/my_board.kicad_pcb")
analyze_3d_models("~/kicad_projects/robot_controller/robot.kicad_pcb")
"""
try:
# Validate the PCB file path
validated_path = validate_kicad_file(pcb_file_path, "pcb")
# Perform 3D analysis
result = analyze_pcb_3d_models(validated_path)
return {
"success": True,
"pcb_file": validated_path,
"analysis": result
}
except Exception as e:
return {
"success": False,
"error": str(e),
"pcb_file": pcb_file_path
}
@mcp.tool()
def check_mechanical_constraints(pcb_file_path: str) -> dict[str, Any]:
"""
Check mechanical constraints and clearances in a KiCad PCB.
Performs comprehensive mechanical analysis including component clearances,
board edge distances, height constraints, and identifies potential
manufacturing or assembly issues.
Args:
pcb_file_path: Path to the .kicad_pcb file to analyze
Returns:
Dictionary containing mechanical analysis results:
- constraints: List of constraint violations
- clearance_violations: Detailed clearance issues
- board_dimensions: Physical board properties
- recommendations: Suggested improvements
"""
try:
validated_path = validate_kicad_file(pcb_file_path, "pcb")
# Perform mechanical analysis
analysis = get_mechanical_constraints(validated_path)
# Generate recommendations
recommendations = []
if analysis.height_analysis["max"] > 5.0:
recommendations.append("Consider using lower profile components to reduce board height")
if len(analysis.clearance_violations) > 0:
recommendations.append("Review component placement to resolve clearance violations")
if analysis.board_dimensions.width > 80 or analysis.board_dimensions.height > 80:
recommendations.append("Large board size may increase manufacturing costs")
return {
"success": True,
"pcb_file": validated_path,
"constraints": analysis.mechanical_constraints,
"clearance_violations": [
{
"type": v["type"],
"components": [v.get("component1", ""), v.get("component2", ""), v.get("component", "")],
"distance": v["distance"],
"required": v["required_clearance"],
"severity": v["severity"]
}
for v in analysis.clearance_violations
],
"board_dimensions": {
"width_mm": analysis.board_dimensions.width,
"height_mm": analysis.board_dimensions.height,
"thickness_mm": analysis.board_dimensions.thickness,
"area_mm2": analysis.board_dimensions.width * analysis.board_dimensions.height
},
"height_analysis": analysis.height_analysis,
"recommendations": recommendations,
"component_count": len(analysis.components)
}
except Exception as e:
return {
"success": False,
"error": str(e),
"pcb_file": pcb_file_path
}
@mcp.tool()
def generate_3d_visualization_json(pcb_file_path: str, output_path: str = None) -> dict[str, Any]:
"""
Generate JSON data file for 3D visualization of PCB.
Creates a structured JSON file containing all necessary data for
3D visualization tools, including component positions, board outline,
and model references.
Args:
pcb_file_path: Path to the .kicad_pcb file
output_path: Optional path for output JSON file (defaults to same dir as PCB)
Returns:
Dictionary with generation results and file path
"""
try:
validated_path = validate_kicad_file(pcb_file_path, "pcb")
# Generate visualization data
viz_data = analyze_pcb_3d_models(validated_path)
# Determine output path
if not output_path:
output_path = validated_path.replace('.kicad_pcb', '_3d_viz.json')
# Save visualization data
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(viz_data, f, indent=2)
return {
"success": True,
"pcb_file": validated_path,
"output_file": output_path,
"component_count": viz_data.get("stats", {}).get("total_components", 0),
"models_found": viz_data.get("stats", {}).get("components_with_3d_models", 0),
"board_size": f"{viz_data.get('board_dimensions', {}).get('width', 0):.1f}x{viz_data.get('board_dimensions', {}).get('height', 0):.1f}mm"
}
except Exception as e:
return {
"success": False,
"error": str(e),
"pcb_file": pcb_file_path
}
@mcp.tool()
def component_height_distribution(pcb_file_path: str) -> dict[str, Any]:
"""
Analyze the height distribution of components on a PCB.
Provides detailed analysis of component heights, useful for
determining enclosure requirements and assembly considerations.
Args:
pcb_file_path: Path to the .kicad_pcb file
Returns:
Height distribution analysis with statistics and component breakdown
"""
try:
validated_path = validate_kicad_file(pcb_file_path, "pcb")
analyzer = Model3DAnalyzer(validated_path)
components = analyzer.extract_3d_components()
height_analysis = analyzer.analyze_component_heights(components)
# Categorize components by height
height_categories = {
"very_low": [], # < 1mm
"low": [], # 1-2mm
"medium": [], # 2-5mm
"high": [], # 5-10mm
"very_high": [] # > 10mm
}
for comp in components:
height = analyzer._estimate_component_height(comp)
if height < 1.0:
height_categories["very_low"].append((comp.reference, height))
elif height < 2.0:
height_categories["low"].append((comp.reference, height))
elif height < 5.0:
height_categories["medium"].append((comp.reference, height))
elif height < 10.0:
height_categories["high"].append((comp.reference, height))
else:
height_categories["very_high"].append((comp.reference, height))
return {
"success": True,
"pcb_file": validated_path,
"height_statistics": height_analysis,
"height_categories": {
category: [{"component": ref, "height_mm": height}
for ref, height in components]
for category, components in height_categories.items()
},
"tallest_components": sorted(
[(comp.reference, analyzer._estimate_component_height(comp))
for comp in components],
key=lambda x: x[1], reverse=True
)[:10], # Top 10 tallest components
"enclosure_requirements": {
"minimum_height_mm": height_analysis["max"] + 2.0, # Add 2mm clearance
"recommended_height_mm": height_analysis["max"] + 5.0 # Add 5mm clearance
}
}
except Exception as e:
return {
"success": False,
"error": str(e),
"pcb_file": pcb_file_path
}
@mcp.tool()
def check_assembly_feasibility(pcb_file_path: str) -> dict[str, Any]:
"""
Analyze PCB assembly feasibility and identify potential issues.
Checks for component accessibility, assembly sequence issues,
and manufacturing constraints that could affect PCB assembly.
Args:
pcb_file_path: Path to the .kicad_pcb file
Returns:
Assembly feasibility analysis with issues and recommendations
"""
try:
validated_path = validate_kicad_file(pcb_file_path, "pcb")
analyzer = Model3DAnalyzer(validated_path)
mechanical_analysis = analyzer.perform_mechanical_analysis()
components = mechanical_analysis.components
assembly_issues = []
assembly_warnings = []
# Check for components too close to board edge
for comp in components:
edge_distance = analyzer._distance_to_board_edge(
comp, mechanical_analysis.board_dimensions
)
if edge_distance < 1.0: # Less than 1mm from edge
assembly_warnings.append({
"component": comp.reference,
"issue": f"Component only {edge_distance:.2f}mm from board edge",
"recommendation": "Consider moving component away from edge for easier assembly"
})
# Check for very small components that might be hard to place
small_component_footprints = ["0201", "0402"]
for comp in components:
if any(size in (comp.footprint or "") for size in small_component_footprints):
assembly_warnings.append({
"component": comp.reference,
"issue": f"Very small footprint {comp.footprint}",
"recommendation": "Verify pick-and-place machine compatibility"
})
# Check component density
board_area = (mechanical_analysis.board_dimensions.width *
mechanical_analysis.board_dimensions.height)
component_density = len(components) / (board_area / 100) # Components per cm²
if component_density > 5.0:
assembly_warnings.append({
"component": "Board",
"issue": f"High component density: {component_density:.1f} components/cm²",
"recommendation": "Consider larger board or fewer components for easier assembly"
})
return {
"success": True,
"pcb_file": validated_path,
"assembly_feasible": len(assembly_issues) == 0,
"assembly_issues": assembly_issues,
"assembly_warnings": assembly_warnings,
"component_density": component_density,
"board_utilization": {
"component_count": len(components),
"board_area_mm2": board_area,
"density_per_cm2": component_density
},
"recommendations": [
"Review component placement for optimal assembly sequence",
"Ensure adequate fiducial markers for automated assembly",
"Consider component orientation for consistent placement direction"
] if assembly_warnings else ["PCB appears suitable for standard assembly processes"]
}
except Exception as e:
return {
"success": False,
"error": str(e),
"pcb_file": pcb_file_path
}