Spaces:
Sleeping
Sleeping
File size: 6,407 Bytes
2ffc08a 4cb7b30 8cf1897 5f5a54f 97b090b 8dd9d51 764678f 8dd9d51 5e1a30a 8dd9d51 5e1a30a d58c03f 8dd9d51 d58c03f 5e1a30a 8dd9d51 5e1a30a d570fcf 4874b7c 5e1a30a 38d8ad7 5e1a30a 38d8ad7 5e1a30a 38d8ad7 5e1a30a 38d8ad7 5e1a30a 9400a0f 5e1a30a 4874b7c 5e1a30a 9400a0f d570fcf 5e1a30a d58c03f 8dd9d51 5e1a30a 8dd9d51 5e1a30a 5f5a54f 5e1a30a d58c03f 5e1a30a d58c03f 5e1a30a d58c03f 5e1a30a d58c03f 5e1a30a d58c03f 5e1a30a d58c03f 8dd9d51 97b090b 8cf1897 97b090b 5e1a30a d58c03f 5e1a30a 8cf1897 9ec48a7 8dd9d51 b3ec31c 5e1a30a b3ec31c 97b090b b3ec31c 5e1a30a b3ec31c 5e1a30a b3ec31c 8cf1897 5e1a30a 8cf1897 5e1a30a 4cb7b30 5e1a30a 8cf1897 5f5a54f 9ec48a7 8cf1897 d58c03f 5f5a54f 5e1a30a 5f5a54f 8cf1897 b3ec31c 97b090b b3ec31c 5f5a54f 97b090b 5e1a30a 5f5a54f 8dd9d51 5f5a54f 9ec48a7 5e1a30a 5f5a54f b3ec31c 5f5a54f 97b090b 2ffc08a ead1974 8cf1897 2ffc08a b5f490a 5e1a30a b5f490a 5e1a30a |
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 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
import os
import socket
import gradio as gr
import cadquery as cq
from cadquery import exporters
import trimesh
from io import BytesIO
import json
import atexit
import glob
# Cleanup function to remove temporary files
def cleanup_temp_files():
temp_files = glob.glob("*.stl") + glob.glob("*.inp")
for temp_file in temp_files:
try:
os.remove(temp_file)
except OSError:
pass
atexit.register(cleanup_temp_files)
# Define 2D and 3D view generation functions with error handling
def generate_2d_view(file):
try:
model = process_cad_file(file)
two_d_image = model.toSvg()
return two_d_image
except Exception as e:
return f"Error generating 2D view: {str(e)}"
def generate_3d_view(file):
try:
# Import CAD file and create a Workplane object
model = cq.importers.importStep(file.name)
# Extract solids from the Workplane object
solids = model.vals() if hasattr(model, 'vals') else model.solids()
if not solids:
raise ValueError("No solids found in the CAD model.")
# Convert solids into trimesh-compatible meshes
meshes = []
for solid in solids:
vertices = []
faces = []
for face in solid.tessellate():
vertices.extend(face[0]) # Extract vertices (x, y, z)
faces.extend([[face[1][i], face[1][i + 1], face[1][i + 2]] for i in range(0, len(face[1]), 3)]) # Triangular faces
mesh = trimesh.Trimesh(vertices=vertices, faces=faces)
meshes.append(mesh)
# Combine all meshes into a single trimesh object if multiple solids exist
combined_mesh = trimesh.util.concatenate(meshes) if len(meshes) > 1 else meshes[0]
# Visualize the mesh
combined_mesh.show()
return "3D view generated successfully."
except Exception as e:
return f"Error generating 3D view: {str(e)}"
# Wrapper function to generate views
def generate_views(file):
try:
two_d_view = generate_2d_view(file)
three_d_view = generate_3d_view(file)
return two_d_view, three_d_view
except Exception as e:
return f"Error: {str(e)}", None
# Function to process different CAD file formats
def process_cad_file(file):
file_extension = os.path.splitext(file.name)[-1].lower()
if file_extension in [".stp", ".step"]:
model = cq.importers.importStep(file.name)
elif file_extension in [".iges", ".igs"]:
model = cq.importers.importStep(file.name) # Same as STEP for cadquery
elif file_extension == ".sldprt":
raise NotImplementedError("SLDPRT support is not yet implemented.")
elif file_extension == ".dwg":
raise NotImplementedError("DWG support is not yet implemented.")
else:
raise ValueError(f"Unsupported file format: {file_extension}")
return model
# APDL script generation
def generate_apdl_script(file, press_force, material_json):
try:
material = json.loads(material_json)
elastic_modulus = material.get("elastic_modulus", 2e11)
poisson = material.get("poisson", 0.3)
# Use temporary file path for processing
step_file_path = file.name
model = process_cad_file(file)
stl_file = step_file_path.replace(".stp", ".stl")
exporters.export(model, stl_file)
apdl_script = f"""\n
/PREP7
! Importing Geometry
/import, '{step_file_path}', geom, STEP
! Material Properties
MP, EX, 1, {elastic_modulus}
MP, PRXY, 1, {poisson}
! Load and Boundary Conditions
F, NODE, ALL, FX, {press_force}
! Solve
/SOLU
SOLVE
/POST1
*GET, stress, NODE, 0, S, MAX
/EXIT, SAVE
"""
apdl_file_path = step_file_path.replace(".stp", ".inp")
with open(apdl_file_path, "w") as apdl_file:
apdl_file.write(apdl_script)
return apdl_script, apdl_file_path
except Exception as e:
return f"Error: {str(e)}", None
# Function to find a free port in a range
def find_free_port(start_port, end_port):
for port in range(start_port, end_port + 1):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
if sock.connect_ex(('localhost', port)) != 0: # Port is free
return port
raise OSError(f"No available ports in range {start_port}-{end_port}")
# Gradio App
def main():
with gr.Blocks() as app:
gr.Markdown("# Press Tool Design and APDL Script Generator")
with gr.Row():
step_input = gr.File(
label="Upload CAD File",
file_types=[".stp", ".step", ".iges", ".igs", ".sldprt", ".dwg"]
)
with gr.Row():
two_d_output = gr.Textbox(label="2D View/Error Message", interactive=False)
three_d_output = gr.Textbox(label="3D View/Error Message", interactive=False)
generate_views_btn = gr.Button("Generate 2D & 3D Views")
with gr.Row():
force_input = gr.Number(label="Press Force (N)", value=1000)
material_input = gr.Textbox(
label="Material Properties (JSON)",
value='{"elastic_modulus": 2e11, "poisson": 0.3}'
)
with gr.Row():
script_output = gr.Textbox(label="Generated APDL Script", interactive=False)
download_button = gr.File(label="Download Script")
generate_apdl_btn = gr.Button("Generate APDL Script")
# Events for Visualization
generate_views_btn.click(
fn=generate_views,
inputs=step_input,
outputs=[two_d_output, three_d_output]
)
# Events for APDL Script
def handle_download(apdl_script, apdl_file_path):
if apdl_file_path and os.path.exists(apdl_file_path):
return apdl_file_path
return None
generate_apdl_btn.click(
fn=generate_apdl_script,
inputs=[step_input, force_input, material_input],
outputs=[script_output, download_button]
)
return app
if __name__ == "__main__":
app = main()
try:
# Dynamically find a free port in range 7860-7870
port = find_free_port(7860, 7870)
print(f"Launching on port: {port}")
app.launch(server_port=port, debug=True)
except Exception as e:
print(f"Failed to launch: {str(e)}") |