@hybridlabor-api/bdb-hardware-pcb 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +116 -0
- package/config/mcp/antigravity.json +22 -0
- package/config/mcp/claude.json +22 -0
- package/config/mcp/codex.toml +25 -0
- package/docs/adr/ADR-001-KICAD-OPENSCAD-MCP-STRATEGY.md +334 -0
- package/docs/review_documentation.md +121 -0
- package/installer.js +358 -0
- package/mcp_servers/kicad-mcp-server/.env.example +22 -0
- package/mcp_servers/kicad-mcp-server/.github/workflows/ci.yml +36 -0
- package/mcp_servers/kicad-mcp-server/CLAUDE.md +487 -0
- package/mcp_servers/kicad-mcp-server/README.md +316 -0
- package/mcp_servers/kicad-mcp-server/docs/DEVICE_TREE.md +416 -0
- package/mcp_servers/kicad-mcp-server/docs/INSTALLATION.md +332 -0
- package/mcp_servers/kicad-mcp-server/docs/PIN_ANALYSIS.md +332 -0
- package/mcp_servers/kicad-mcp-server/docs/README.md +240 -0
- package/mcp_servers/kicad-mcp-server/docs/TESTING.md +613 -0
- package/mcp_servers/kicad-mcp-server/docs/VALIDATION.md +268 -0
- package/mcp_servers/kicad-mcp-server/pyproject.toml +96 -0
- package/mcp_servers/kicad-mcp-server/requirements-dev.txt +16 -0
- package/mcp_servers/kicad-mcp-server/requirements-test.txt +24 -0
- package/mcp_servers/kicad-mcp-server/requirements.txt +13 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/__init__.py +3 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/__main__.py +17 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/config.py +46 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/models/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/models/types.py +87 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/netlist_parser.py +234 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/pcb_parser.py +375 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/pcb_parser_kicad.py +327 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/schematic_parser.py +902 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/server.py +71 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/arduino/connectivity_test.cpp.j2 +189 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/atmega.dts.j2 +77 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/esp32.dts.j2 +77 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/nrf52.dts.j2 +77 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/stm32f4.dts.j2 +89 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/esp_idf/test_suite.c.j2 +340 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/pytest/test_connectivity.py.j2 +147 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/st_hal/hal_test.c.j2 +313 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_gpio_test.py.j2 +99 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_i2c_test.py.j2 +117 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_pinmux_test.py.j2 +43 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_spi_test.py.j2 +94 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_gpio_test.c.j2 +113 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_i2c_test.c.j2 +101 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_spi_test.c.j2 +94 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/unittest/test_schematic.py.j2 +172 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/__init__.py +36 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/device_tree.py +1187 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/hierarchical_analysis.py +211 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/netlist.py +320 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/parts_registry.py +142 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pcb.py +955 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pcb_layout.py +308 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pin_analysis.py +765 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/project.py +196 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic.py +319 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic_editor.py +674 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic_search.py +158 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/validation.py +866 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/visualization.py +225 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/file_handlers.py +65 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/kicad_cli.py +103 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/kicad_version.py +103 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/parts_registry.py +197 -0
- package/mcp_servers/kicad-mcp-server/tests/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/tests/examples/ESP32S3_TEST.md +219 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/README.md +65 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/example_pcb.kicad_pcb +177 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/example_schematic.kicad_sch +145 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/hier/child.kicad_sch +24 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/hier/root.kicad_sch +38 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_hierarchical_labels.py +195 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_kicad_cli.py +116 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_netlist_cache_path.py +29 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_schematic.py +189 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_schematic_hierarchy.py +69 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_visualization.py +136 -0
- package/mcp_servers/kicad-mcp-server/uv.lock +2873 -0
- package/mcp_servers/openscad-mcp-server/.dockerignore +9 -0
- package/mcp_servers/openscad-mcp-server/.github/workflows/test.yml +40 -0
- package/mcp_servers/openscad-mcp-server/Dockerfile +29 -0
- package/mcp_servers/openscad-mcp-server/LICENSE +21 -0
- package/mcp_servers/openscad-mcp-server/README.md +154 -0
- package/mcp_servers/openscad-mcp-server/docs/audit.md +56 -0
- package/mcp_servers/openscad-mcp-server/docs/docker.md +66 -0
- package/mcp_servers/openscad-mcp-server/docs/issue-followup.md +19 -0
- package/mcp_servers/openscad-mcp-server/docs/jetson.md +17 -0
- package/mcp_servers/openscad-mcp-server/glama.json +4 -0
- package/mcp_servers/openscad-mcp-server/legacy/README.md +15 -0
- package/mcp_servers/openscad-mcp-server/legacy/README.original.md +294 -0
- package/mcp_servers/openscad-mcp-server/legacy/implementation_plan.md +100 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/download_sam2_checkpoint.py +115 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/src/ai/sam_segmentation.py +209 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/src/models/threestudio_generator.py +231 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/src/workflow/image_to_model_pipeline.py +260 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/test_sam2_segmentation.py +96 -0
- package/mcp_servers/openscad-mcp-server/legacy/requirements.txt +57 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/README.md +39 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/decisions/ai-driven-code-generation.md +122 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/decisions/export-formats.md +76 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/ai/ai_service.py.md +51 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/main.py.md +63 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/models/code_generator.py.md +63 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/nlp/parameter_extractor.py.md +63 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/ai/natural-language-processing.md +78 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/nlp/parameter-extraction.md +173 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/export-formats.md +91 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/openscad-basics.md +66 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/primitive-testing.md +79 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/ai/ai_service.py +257 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/ai/gemini_api.py +161 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/ai/venice_api.py +203 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/config.py +121 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/main.py +1456 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/main.py.new +404 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/main_remote.py +401 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/models/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/models/code_generator.py +321 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/models/cuda_mvs.py +209 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/models/scad_templates/basic_shapes.scad +144 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/nlp/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/nlp/parameter_extractor.py +388 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/openscad_wrapper/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/openscad_wrapper/wrapper.py +418 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/printer_discovery/__init__.py +1 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/printer_discovery/printer_discovery.py +471 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/remote/connection_manager.py +537 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/remote/cuda_mvs_client.py +435 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/remote/cuda_mvs_server.py +787 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/remote/error_handling.py +415 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/testing/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/testing/primitive_tester.py +203 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/testing/test_primitives.py +98 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/__init__.py +1 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/cad_exporter.py +241 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/format_validator.py +206 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_exporter.py +140 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_repair.py +91 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_validator.py +123 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/visualization/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/visualization/headless_renderer.py +52 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/visualization/renderer.py +177 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/visualization/web_interface.py +639 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/workflow/image_approval.py +148 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/workflow/multi_view_to_model_pipeline.py +338 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_complete_workflow.py +374 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_cuda_mvs.py +191 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_gemini_api.py +168 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_image_approval.py +192 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_image_approval_workflow.py +251 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_image_to_model_pipeline.py +145 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_model_selection.py +41 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_multi_view_pipeline.py +290 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_primitives.sh +13 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_rabbit_direct.py +71 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_remote_cuda_mvs.py +283 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_venice_example.py +69 -0
- package/mcp_servers/openscad-mcp-server/pyproject.toml +33 -0
- package/mcp_servers/openscad-mcp-server/requirements.txt +2 -0
- package/mcp_servers/openscad-mcp-server/scad/simple_cube.scad +2 -0
- package/mcp_servers/openscad-mcp-server/scripts/test_docker.py +220 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/__init__.py +3 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/__main__.py +3 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/engine.py +94 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/geometry.py +242 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/server.py +245 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/service.py +190 -0
- package/mcp_servers/openscad-mcp-server/tests/conftest.py +17 -0
- package/mcp_servers/openscad-mcp-server/tests/test_engine.py +37 -0
- package/mcp_servers/openscad-mcp-server/tests/test_geometry.py +106 -0
- package/mcp_servers/openscad-mcp-server/tests/test_integration.py +172 -0
- package/mcp_servers/openscad-mcp-server/tests/test_transports.py +314 -0
- package/mcp_servers/openscad-mcp-server/uv.lock +1123 -0
- package/package.json +44 -0
- package/scripts/install_mcps.sh +86 -0
- package/scripts/openscad_wrapper.sh +62 -0
- package/scripts/run_kicad_mcp.sh +25 -0
- package/scripts/run_openscad_mcp.sh +41 -0
- package/scripts/test_mcp_connection.py +626 -0
- package/scripts/test_mcp_connection.sh +168 -0
- package/skills/code-first-hardware-design/SKILL.md +260 -0
- package/skills/pcb-constraint-definition/SKILL.md +236 -0
- package/skills/pcb-layout-routing-automation/SKILL.md +153 -0
- package/skills/pcb-validation-dfm-signoff/SKILL.md +194 -0
- package/skills/schematic-datasheet-analysis/SKILL.md +202 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import logging
|
|
3
|
+
import uuid
|
|
4
|
+
import json
|
|
5
|
+
from typing import Dict, Any, List, Optional, Tuple
|
|
6
|
+
from fastapi import FastAPI, Request, Response, HTTPException
|
|
7
|
+
from fastapi.responses import JSONResponse, FileResponse
|
|
8
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
9
|
+
from fastapi.staticfiles import StaticFiles
|
|
10
|
+
from fastapi.templating import Jinja2Templates
|
|
11
|
+
import uvicorn
|
|
12
|
+
from mcp import MCPServer, MCPTool, MCPToolCall, MCPToolCallResult
|
|
13
|
+
|
|
14
|
+
# Import configuration
|
|
15
|
+
from src.config import *
|
|
16
|
+
|
|
17
|
+
# Import components
|
|
18
|
+
from src.nlp.parameter_extractor import ParameterExtractor
|
|
19
|
+
from src.models.code_generator import CodeGenerator
|
|
20
|
+
from src.openscad_wrapper.wrapper import OpenSCADWrapper
|
|
21
|
+
from src.utils.cad_exporter import CADExporter
|
|
22
|
+
from src.visualization.headless_renderer import HeadlessRenderer
|
|
23
|
+
from src.printer_discovery.printer_discovery import PrinterDiscovery, PrinterInterface
|
|
24
|
+
|
|
25
|
+
# Import AI components
|
|
26
|
+
from src.ai.venice_api import VeniceImageGenerator
|
|
27
|
+
from src.ai.gemini_api import GeminiImageGenerator
|
|
28
|
+
from src.models.cuda_mvs import CUDAMultiViewStereo
|
|
29
|
+
from src.workflow.image_approval import ImageApprovalTool
|
|
30
|
+
from src.workflow.multi_view_to_model_pipeline import MultiViewToModelPipeline
|
|
31
|
+
|
|
32
|
+
# Configure logging
|
|
33
|
+
logging.basicConfig(
|
|
34
|
+
level=logging.INFO,
|
|
35
|
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
36
|
+
)
|
|
37
|
+
logger = logging.getLogger(__name__)
|
|
38
|
+
|
|
39
|
+
# Create FastAPI app
|
|
40
|
+
app = FastAPI(title="OpenSCAD MCP Server")
|
|
41
|
+
|
|
42
|
+
# Add CORS middleware
|
|
43
|
+
app.add_middleware(
|
|
44
|
+
CORSMiddleware,
|
|
45
|
+
allow_origins=["*"],
|
|
46
|
+
allow_credentials=True,
|
|
47
|
+
allow_methods=["*"],
|
|
48
|
+
allow_headers=["*"],
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Create directories
|
|
52
|
+
os.makedirs("scad", exist_ok=True)
|
|
53
|
+
os.makedirs("output", exist_ok=True)
|
|
54
|
+
os.makedirs("output/models", exist_ok=True)
|
|
55
|
+
os.makedirs("output/preview", exist_ok=True)
|
|
56
|
+
os.makedirs("output/images", exist_ok=True)
|
|
57
|
+
os.makedirs("output/multi_view", exist_ok=True)
|
|
58
|
+
os.makedirs("output/approved_images", exist_ok=True)
|
|
59
|
+
os.makedirs("templates", exist_ok=True)
|
|
60
|
+
os.makedirs("static", exist_ok=True)
|
|
61
|
+
|
|
62
|
+
# Initialize components
|
|
63
|
+
parameter_extractor = ParameterExtractor()
|
|
64
|
+
code_generator = CodeGenerator("scad", "output")
|
|
65
|
+
openscad_wrapper = OpenSCADWrapper("scad", "output")
|
|
66
|
+
cad_exporter = CADExporter()
|
|
67
|
+
headless_renderer = HeadlessRenderer()
|
|
68
|
+
printer_discovery = PrinterDiscovery()
|
|
69
|
+
|
|
70
|
+
# Initialize AI components
|
|
71
|
+
venice_generator = None
|
|
72
|
+
gemini_generator = None
|
|
73
|
+
cuda_mvs = None
|
|
74
|
+
approval_tool = None
|
|
75
|
+
multi_view_pipeline = None
|
|
76
|
+
|
|
77
|
+
# Initialize Venice.ai generator if API key is available
|
|
78
|
+
if VENICE_API_KEY:
|
|
79
|
+
venice_generator = VeniceImageGenerator(VENICE_API_KEY, IMAGES_DIR)
|
|
80
|
+
logger.info("Venice.ai image generator initialized")
|
|
81
|
+
else:
|
|
82
|
+
logger.info("Venice.ai API key not provided, skipping initialization")
|
|
83
|
+
|
|
84
|
+
# Initialize Google Gemini generator if API key is available
|
|
85
|
+
if GEMINI_API_KEY:
|
|
86
|
+
gemini_generator = GeminiImageGenerator(GEMINI_API_KEY, IMAGES_DIR)
|
|
87
|
+
logger.info("Google Gemini image generator initialized")
|
|
88
|
+
else:
|
|
89
|
+
logger.warning("Google Gemini API key not provided, multi-view workflow will not be available")
|
|
90
|
+
|
|
91
|
+
# Initialize CUDA MVS if path is available
|
|
92
|
+
if os.path.exists(CUDA_MVS_PATH):
|
|
93
|
+
cuda_mvs = CUDAMultiViewStereo(CUDA_MVS_PATH, MODELS_DIR)
|
|
94
|
+
logger.info("CUDA Multi-View Stereo initialized")
|
|
95
|
+
else:
|
|
96
|
+
logger.warning(f"CUDA MVS not found at {CUDA_MVS_PATH}, 3D reconstruction will not be available")
|
|
97
|
+
|
|
98
|
+
# Initialize image approval tool
|
|
99
|
+
approval_tool = ImageApprovalTool(APPROVED_IMAGES_DIR)
|
|
100
|
+
logger.info("Image approval tool initialized")
|
|
101
|
+
|
|
102
|
+
# Initialize multi-view pipeline if required components are available
|
|
103
|
+
if gemini_generator and cuda_mvs:
|
|
104
|
+
multi_view_pipeline = MultiViewToModelPipeline(
|
|
105
|
+
gemini_generator=gemini_generator,
|
|
106
|
+
venice_generator=venice_generator,
|
|
107
|
+
cuda_mvs=cuda_mvs,
|
|
108
|
+
openscad_wrapper=openscad_wrapper,
|
|
109
|
+
approval_tool=approval_tool,
|
|
110
|
+
output_dir=OUTPUT_DIR
|
|
111
|
+
)
|
|
112
|
+
logger.info("Multi-view to model pipeline initialized")
|
|
113
|
+
else:
|
|
114
|
+
logger.warning("Multi-view to model pipeline not initialized due to missing components")
|
|
115
|
+
|
|
116
|
+
# Store models in memory
|
|
117
|
+
models = {}
|
|
118
|
+
printers = {}
|
|
119
|
+
|
|
120
|
+
# Create MCP server
|
|
121
|
+
mcp_server = MCPServer()
|
|
122
|
+
|
|
123
|
+
# Mount static files
|
|
124
|
+
app.mount("/static", StaticFiles(directory="static"), name="static")
|
|
125
|
+
|
|
126
|
+
# Create Jinja2 templates
|
|
127
|
+
templates = Jinja2Templates(directory="templates")
|
|
128
|
+
|
|
129
|
+
# Create model preview template
|
|
130
|
+
with open("templates/preview.html", "w") as f:
|
|
131
|
+
f.write("""
|
|
132
|
+
<!DOCTYPE html>
|
|
133
|
+
<html lang="en">
|
|
134
|
+
<head>
|
|
135
|
+
<meta charset="UTF-8">
|
|
136
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
137
|
+
<title>OpenSCAD Model Preview</title>
|
|
138
|
+
<style>
|
|
139
|
+
body {
|
|
140
|
+
font-family: Arial, sans-serif;
|
|
141
|
+
margin: 0;
|
|
142
|
+
padding: 0;
|
|
143
|
+
background-color: #f5f5f5;
|
|
144
|
+
}
|
|
145
|
+
.container {
|
|
146
|
+
max-width: 1200px;
|
|
147
|
+
margin: 0 auto;
|
|
148
|
+
padding: 20px;
|
|
149
|
+
}
|
|
150
|
+
h1 {
|
|
151
|
+
color: #333;
|
|
152
|
+
margin-bottom: 20px;
|
|
153
|
+
}
|
|
154
|
+
.preview-container {
|
|
155
|
+
display: flex;
|
|
156
|
+
flex-wrap: wrap;
|
|
157
|
+
gap: 20px;
|
|
158
|
+
margin-top: 20px;
|
|
159
|
+
}
|
|
160
|
+
.preview-image {
|
|
161
|
+
border: 1px solid #ddd;
|
|
162
|
+
border-radius: 5px;
|
|
163
|
+
padding: 10px;
|
|
164
|
+
background-color: white;
|
|
165
|
+
}
|
|
166
|
+
.preview-image img {
|
|
167
|
+
max-width: 100%;
|
|
168
|
+
height: auto;
|
|
169
|
+
}
|
|
170
|
+
.preview-image h3 {
|
|
171
|
+
margin-top: 10px;
|
|
172
|
+
margin-bottom: 5px;
|
|
173
|
+
color: #555;
|
|
174
|
+
}
|
|
175
|
+
.parameters {
|
|
176
|
+
margin-top: 20px;
|
|
177
|
+
background-color: #f9f9f9;
|
|
178
|
+
padding: 15px;
|
|
179
|
+
border-radius: 5px;
|
|
180
|
+
border: 1px solid #eee;
|
|
181
|
+
}
|
|
182
|
+
.parameters h2 {
|
|
183
|
+
margin-top: 0;
|
|
184
|
+
color: #333;
|
|
185
|
+
}
|
|
186
|
+
.parameters table {
|
|
187
|
+
width: 100%;
|
|
188
|
+
border-collapse: collapse;
|
|
189
|
+
}
|
|
190
|
+
.parameters table th, .parameters table td {
|
|
191
|
+
padding: 8px;
|
|
192
|
+
text-align: left;
|
|
193
|
+
border-bottom: 1px solid #ddd;
|
|
194
|
+
}
|
|
195
|
+
.parameters table th {
|
|
196
|
+
background-color: #f2f2f2;
|
|
197
|
+
}
|
|
198
|
+
.actions {
|
|
199
|
+
margin-top: 20px;
|
|
200
|
+
display: flex;
|
|
201
|
+
gap: 10px;
|
|
202
|
+
}
|
|
203
|
+
.actions button {
|
|
204
|
+
padding: 10px 15px;
|
|
205
|
+
background-color: #4CAF50;
|
|
206
|
+
color: white;
|
|
207
|
+
border: none;
|
|
208
|
+
border-radius: 4px;
|
|
209
|
+
cursor: pointer;
|
|
210
|
+
}
|
|
211
|
+
.actions button:hover {
|
|
212
|
+
background-color: #45a049;
|
|
213
|
+
}
|
|
214
|
+
</style>
|
|
215
|
+
</head>
|
|
216
|
+
<body>
|
|
217
|
+
<div class="container">
|
|
218
|
+
<h1>OpenSCAD Model Preview: {{ model_id }}</h1>
|
|
219
|
+
|
|
220
|
+
<div class="parameters">
|
|
221
|
+
<h2>Parameters</h2>
|
|
222
|
+
<table>
|
|
223
|
+
<tr>
|
|
224
|
+
<th>Parameter</th>
|
|
225
|
+
<th>Value</th>
|
|
226
|
+
</tr>
|
|
227
|
+
{% for key, value in parameters.items() %}
|
|
228
|
+
<tr>
|
|
229
|
+
<td>{{ key }}</td>
|
|
230
|
+
<td>{{ value }}</td>
|
|
231
|
+
</tr>
|
|
232
|
+
{% endfor %}
|
|
233
|
+
</table>
|
|
234
|
+
</div>
|
|
235
|
+
|
|
236
|
+
<div class="preview-container">
|
|
237
|
+
{% for view, image_path in previews.items() %}
|
|
238
|
+
<div class="preview-image">
|
|
239
|
+
<h3>{{ view|title }} View</h3>
|
|
240
|
+
<img src="{{ image_path }}" alt="{{ view }} view">
|
|
241
|
+
</div>
|
|
242
|
+
{% endfor %}
|
|
243
|
+
</div>
|
|
244
|
+
|
|
245
|
+
<div class="actions">
|
|
246
|
+
<button onclick="window.location.href='/download/{{ model_id }}'">Download Model</button>
|
|
247
|
+
</div>
|
|
248
|
+
</div>
|
|
249
|
+
</body>
|
|
250
|
+
</html>
|
|
251
|
+
""")
|
|
252
|
+
|
|
253
|
+
# Create multi-view approval template
|
|
254
|
+
with open("templates/multi_view_approval.html", "w") as f:
|
|
255
|
+
f.write("""
|
|
256
|
+
<!DOCTYPE html>
|
|
257
|
+
<html lang="en">
|
|
258
|
+
<head>
|
|
259
|
+
<meta charset="UTF-8">
|
|
260
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
261
|
+
<title>Multi-View Image Approval</title>
|
|
262
|
+
<style>
|
|
263
|
+
body {
|
|
264
|
+
font-family: Arial, sans-serif;
|
|
265
|
+
margin: 0;
|
|
266
|
+
padding: 0;
|
|
267
|
+
background-color: #f5f5f5;
|
|
268
|
+
}
|
|
269
|
+
.container {
|
|
270
|
+
max-width: 1200px;
|
|
271
|
+
margin: 0 auto;
|
|
272
|
+
padding: 20px;
|
|
273
|
+
}
|
|
274
|
+
h1 {
|
|
275
|
+
color: #333;
|
|
276
|
+
margin-bottom: 20px;
|
|
277
|
+
}
|
|
278
|
+
.images-container {
|
|
279
|
+
display: flex;
|
|
280
|
+
flex-wrap: wrap;
|
|
281
|
+
gap: 20px;
|
|
282
|
+
margin-top: 20px;
|
|
283
|
+
}
|
|
284
|
+
.image-card {
|
|
285
|
+
border: 1px solid #ddd;
|
|
286
|
+
border-radius: 5px;
|
|
287
|
+
padding: 10px;
|
|
288
|
+
background-color: white;
|
|
289
|
+
width: calc(50% - 20px);
|
|
290
|
+
box-sizing: border-box;
|
|
291
|
+
}
|
|
292
|
+
.image-card img {
|
|
293
|
+
max-width: 100%;
|
|
294
|
+
height: auto;
|
|
295
|
+
}
|
|
296
|
+
.image-card h3 {
|
|
297
|
+
margin-top: 10px;
|
|
298
|
+
margin-bottom: 5px;
|
|
299
|
+
color: #555;
|
|
300
|
+
}
|
|
301
|
+
.image-card .metadata {
|
|
302
|
+
font-size: 0.9em;
|
|
303
|
+
color: #777;
|
|
304
|
+
margin-bottom: 10px;
|
|
305
|
+
}
|
|
306
|
+
.image-card .actions {
|
|
307
|
+
display: flex;
|
|
308
|
+
gap: 10px;
|
|
309
|
+
margin-top: 10px;
|
|
310
|
+
}
|
|
311
|
+
.image-card .actions button {
|
|
312
|
+
padding: 8px 12px;
|
|
313
|
+
border: none;
|
|
314
|
+
border-radius: 4px;
|
|
315
|
+
cursor: pointer;
|
|
316
|
+
}
|
|
317
|
+
.approve-btn {
|
|
318
|
+
background-color: #4CAF50;
|
|
319
|
+
color: white;
|
|
320
|
+
}
|
|
321
|
+
.approve-btn:hover {
|
|
322
|
+
background-color: #45a049;
|
|
323
|
+
}
|
|
324
|
+
.deny-btn {
|
|
325
|
+
background-color: #f44336;
|
|
326
|
+
color: white;
|
|
327
|
+
}
|
|
328
|
+
.deny-btn:hover {
|
|
329
|
+
background-color: #d32f2f;
|
|
330
|
+
}
|
|
331
|
+
.submit-container {
|
|
332
|
+
margin-top: 20px;
|
|
333
|
+
text-align: center;
|
|
334
|
+
}
|
|
335
|
+
.submit-container button {
|
|
336
|
+
padding: 10px 20px;
|
|
337
|
+
background-color: #2196F3;
|
|
338
|
+
color: white;
|
|
339
|
+
border: none;
|
|
340
|
+
border-radius: 4px;
|
|
341
|
+
cursor: pointer;
|
|
342
|
+
font-size: 1.1em;
|
|
343
|
+
}
|
|
344
|
+
.submit-container button:hover {
|
|
345
|
+
background-color: #0b7dda;
|
|
346
|
+
}
|
|
347
|
+
</style>
|
|
348
|
+
<script>
|
|
349
|
+
function toggleApproval(id, approved) {
|
|
350
|
+
const card = document.getElementById(`card-${id}`);
|
|
351
|
+
const approveBtn = document.getElementById(`approve-${id}`);
|
|
352
|
+
const denyBtn = document.getElementById(`deny-${id}`);
|
|
353
|
+
|
|
354
|
+
if (approved) {
|
|
355
|
+
card.style.borderColor = '#4CAF50';
|
|
356
|
+
approveBtn.disabled = true;
|
|
357
|
+
denyBtn.disabled = false;
|
|
358
|
+
} else {
|
|
359
|
+
card.style.borderColor = '#f44336';
|
|
360
|
+
approveBtn.disabled = false;
|
|
361
|
+
denyBtn.disabled = true;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
document.getElementById(`approval-${id}`).value = approved;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function submitApprovals() {
|
|
368
|
+
document.getElementById('approval-form').submit();
|
|
369
|
+
}
|
|
370
|
+
</script>
|
|
371
|
+
</head>
|
|
372
|
+
<body>
|
|
373
|
+
<div class="container">
|
|
374
|
+
<h1>Multi-View Image Approval</h1>
|
|
375
|
+
<p>Please approve or deny each image for 3D reconstruction.</p>
|
|
376
|
+
|
|
377
|
+
<form id="approval-form" action="/approve_images" method="post">
|
|
378
|
+
<input type="hidden" name="pipeline_id" value="{{ pipeline_id }}">
|
|
379
|
+
|
|
380
|
+
<div class="images-container">
|
|
381
|
+
{% for image in images %}
|
|
382
|
+
<div id="card-{{ image.approval_id }}" class="image-card">
|
|
383
|
+
<h3>{{ image.metadata.view_direction }}</h3>
|
|
384
|
+
<div class="metadata">
|
|
385
|
+
<p>{{ image.metadata.prompt }}</p>
|
|
386
|
+
</div>
|
|
387
|
+
<img src="{{ image.image_url }}" alt="{{ image.metadata.view_direction }}">
|
|
388
|
+
<input type="hidden" id="approval-{{ image.approval_id }}" name="approvals[{{ image.approval_id }}]" value="false">
|
|
389
|
+
<div class="actions">
|
|
390
|
+
<button id="approve-{{ image.approval_id }}" type="button" class="approve-btn" onclick="toggleApproval('{{ image.approval_id }}', true)">Approve</button>
|
|
391
|
+
<button id="deny-{{ image.approval_id }}" type="button" class="deny-btn" onclick="toggleApproval('{{ image.approval_id }}', false)">Deny</button>
|
|
392
|
+
</div>
|
|
393
|
+
</div>
|
|
394
|
+
{% endfor %}
|
|
395
|
+
</div>
|
|
396
|
+
|
|
397
|
+
<div class="submit-container">
|
|
398
|
+
<button type="button" onclick="submitApprovals()">Submit Approvals</button>
|
|
399
|
+
</div>
|
|
400
|
+
</form>
|
|
401
|
+
</div>
|
|
402
|
+
</body>
|
|
403
|
+
</html>
|
|
404
|
+
""")
|