File size: 5,124 Bytes
41d6e2b
 
dddf9a7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41d6e2b
dddf9a7
 
 
89f261c
 
 
 
 
 
 
41d6e2b
dddf9a7
 
 
 
 
 
 
 
89f261c
dddf9a7
 
 
 
 
 
 
 
 
 
 
41d6e2b
dddf9a7
 
41d6e2b
dddf9a7
 
 
41d6e2b
dddf9a7
89f261c
dddf9a7
 
41d6e2b
dddf9a7
41d6e2b
dddf9a7
 
 
66f12a9
 
dddf9a7
41d6e2b
dddf9a7
 
 
 
 
 
89f261c
dddf9a7
41d6e2b
 
dddf9a7
41d6e2b
 
dddf9a7
 
 
 
 
 
 
 
 
 
 
89f261c
dddf9a7
 
 
 
 
 
 
89f261c
dddf9a7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41d6e2b
 
dddf9a7
 
 
41d6e2b
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import gradio as gr
from pathlib import Path
import sys

# Paths
PROJECT_ROOT = Path(__file__).resolve().parent
GENERATED_SCRIPT_PATH = PROJECT_ROOT / "generated" / "result_script.py"

# Add root to sys.path so we can import process.py from app/
sys.path.insert(0, str(PROJECT_ROOT / "app"))

from app.process import main as generate_from_llm  # This runs generation

def generate_script_and_preview(description):
    """
    Generates the FreeCAD script using process.py logic and returns:
    - The script text for preview
    - The file path for download
    """
    import builtins
    original_input = builtins.input
    builtins.input = lambda _: description
    try:
        generate_from_llm()
    finally:
        builtins.input = original_input

    if GENERATED_SCRIPT_PATH.exists():
        script_text = GENERATED_SCRIPT_PATH.read_text(encoding="utf-8")
        return script_text, str(GENERATED_SCRIPT_PATH)
    else:
        return "Error: Script was not generated.", None


css = """
    body { background-color: #202020; color: white; margin: 0; padding: 0; }
    .gradio-container {
        max-width: 1400px;
        width: 95vw;
        margin: auto;
    }
    .title { text-align: center; font-size: 2.5em; margin-bottom: 0.1em; }
    .description { text-align: center; font-size: 1.1em; margin-bottom: 1em; color: #ccc; }
    .preview-box { 
        max-height: 400px;
        background-color: #111;
        border: 1px solid #444;
        padding: 10px;
        font-family: monospace;
        white-space: pre-wrap;
        color: #0f0;
    }
    .download-container {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        gap: 0.5em;
        padding-left: 15px;
        height: 400px;
        justify-content: flex-start;
        width: 500px;
    }
    .download-button { width: 100%; }
    .instructions {
        font-size: 0.9em; color: #aaa;
        max-width: 300px;
        white-space: pre-line;
    }
    .footer { 
        margin-top: 2em; 
        text-align: center; 
        font-size: 0.9em; 
        color: #888;
        border-top: 1px solid #444;
        padding-top: 1em;
    }
    .footer a { color: #6af; text-decoration: none; }
    .footer a:hover { text-decoration: underline; }
"""

# Description 
# ToDo write as features
cadomatic_description_md = """ 
<div style="text-align: center;">

Seamlessly creating python scripts for FreeCAD — from prompt to model.

CADomatic is a Python-powered tool that transforms prompts into **editable** parametric CAD scripts for FreeCAD. Rather than static models, it generates fully customizable Python code that programmatically builds CAD geometry — enabling engineers to define parts, reuse templates, and iterate rapidly.<br>
CADomatic primarily aims at **reducing product development time** by making a base design which can be modified to suit the designer's main goal.<br>
CADomatic creates native FreeCAD Python scripts for simple parts **with a complete design tree**.<br>
 <br>
Explore [CADomatic on GitHub](https://github.com/yas1nsyed/CADomatic) and if you find it useful, please ⭐ star the repository!
"""

with gr.Blocks(css=css) as demo:
    gr.Markdown("<div class='title'>CADomatic - AI powered CAD design generator</div>") # Title
    gr.Markdown(cadomatic_description_md)

    description_input = gr.Textbox(
        label="Describe your desired CAD model below-",
        lines=2,
        placeholder="e.g., Create a flange with OD 100mm, bore size 50mm and 6 m8 holes at PCD 75mm..."
    )

    generate_btn = gr.Button("Generate Script", variant="primary")

    with gr.Row():
        with gr.Column(scale=1):
            preview_output = gr.Code(
                label="Generated Script Preview",
                language="python",
                elem_classes="preview-box"
            )
            download_btn = gr.DownloadButton(
                label="Download Python Script",
                elem_classes="download-button"
            )
        with gr.Column(scale=1):
            gr.Markdown( #ToDo 
                """
                <div class='instructions'>
                <b>Instructions:</b><br>
                - Enter the description for your desired CAD part.<br>
                - Click on "Generate Script".<br>
                - Preview the generated Python code.<br>
                - Paste the generated code into the python console of your FreeCAD app.<br>
                - (or)<br> 
                - Download the script.<br>
                - In your FreeCAD python console, paste - exec(open(r"path to your python script").read())
                </div>
                """
            )

    # Footer
    gr.Markdown( 
        """
        <div class='footer'>
        CADomatic is still under development and may sometimes produce inaccurate results.<br>
         <br>
        Made with ❤️ by Yasin
        </div>
        """
    )

    generate_btn.click(
        fn=generate_script_and_preview,
        inputs=description_input,
        outputs=[preview_output, download_btn]
    )

if __name__ == "__main__":
    demo.launch()