import gradio as gr import os import cv2 import numpy as np from OCC.Extend.DataExchange import read_step_file from OCC.Core.BRepBnd import Bnd_Box from OCC.Core.gp import gp_Pnt from OCC.Core.BRep import BRep_Builder from OCC.Core.TopAbs import TopAbs_SOLID from OCC.Core.TopoDS import topods_Solid from OCC.Core.STEPControl import STEPControl_Reader # Function to process image and extract dimensions (example: simple edge detection) def process_image_for_dimensions(image_file_path): """ Process CAD image to extract dimensions. For simplicity, we assume a 2D image where we can detect the outline or significant objects. """ # Load image image = cv2.imread(image_file_path, cv2.IMREAD_GRAYSCALE) _, thresholded = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY) # Find contours of the image contours, _ = cv2.findContours(thresholded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: raise ValueError("No contours found in the image.") # Get the bounding box of the largest contour (assuming it's the object of interest) contour = max(contours, key=cv2.contourArea) x, y, w, h = cv2.boundingRect(contour) # Example: assume extracted dimensions from bounding box width = w # Width of the bounding box height = h # Height of the bounding box depth = 50 # Default depth, you can modify this based on input or assumptions # Return the extracted dimensions return (width, height, depth) # Function to process STEP file and extract dimensions def process_step_file(step_file_path): """ Process a STEP file to extract the 3D bounding box dimensions of the geometry. """ # Read the STEP file reader = STEPControl_Reader() status = reader.ReadFile(step_file_path) if status != 1: raise ValueError(f"Failed to load STEP file: {step_file_path}") # Get the shape from the STEP file shape = reader.Shape() # Calculate bounding box bbox = Bnd_Box() builder = BRep_Builder() builder.Add(bbox, shape) # Get the bounds of the box xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() # Return dimensions (width, height, depth) width = xmax - xmin height = ymax - ymin depth = zmax - zmin return (width, height, depth) # Function to generate APDL script from extracted properties def generate_apdl_script(cad_file, element_type, material_ex, material_nu): """ Generate an APDL script based on CAD file properties and user input. """ file_extension = os.path.splitext(cad_file.name)[1].lower() # Extract dimensions based on the file type if file_extension in ['.png', '.jpg', '.jpeg', '.bmp']: # For image files cad_dimensions = process_image_for_dimensions(cad_file.name) elif file_extension in ['.step', '.stp']: # For STEP files cad_dimensions = process_step_file(cad_file.name) else: raise ValueError(f"Unsupported CAD file format: {file_extension}") # File name for the generated APDL script file_name = "generated_apdl_script.inp" # Generate the APDL script with open(file_name, 'w') as apdl_file: apdl_file.write("! APDL Script Generated from CAD File\n") apdl_file.write("/PREP7\n") apdl_file.write(f"ET,1,{element_type}\n") # Define element type apdl_file.write(f"BLOCK,0,{cad_dimensions[0]},0,{cad_dimensions[1]},0,{cad_dimensions[2]}\n") # Create a block apdl_file.write(f"MP,EX,1,{material_ex}\n") # Define material property (Young's modulus) apdl_file.write(f"MP,NUXY,1,{material_nu}\n") # Define material property (Poisson's ratio) apdl_file.write("MAT,1\n") apdl_file.write("ESEL,S,ALL\n") # Select all elements apdl_file.write("ESIZE,10\n") # Element size apdl_file.write("MSHAPE,1,3D\n") # Define mesh shape apdl_file.write("MESH,ALL\n") # Generate the mesh apdl_file.write("/SOLU\n") # Switch to solution processor apdl_file.write("ANTYPE,STATIC\n") # Define analysis type apdl_file.write("D,1,UX,0\n") # Apply boundary condition (UX=0) apdl_file.write("D,1,UY,0\n") # Apply boundary condition (UY=0) apdl_file.write("D,1,UZ,0\n") # Apply boundary condition (UZ=0) apdl_file.write("FINISH\n") # Finish pre-processing apdl_file.write("/POST1\n") # Post-processing apdl_file.write("SET,LAST\n") # Use the last result set apdl_file.write("PLDISP,ALL\n") # Plot displacement apdl_file.write("FINISH\n") # Finish post-processing return file_name # Gradio Interface for CAD File Input (Image or STEP) def generate_script_ui_from_cad(cad_file, element_type, material_ex, material_nu): """ Interface function to generate an APDL script from CAD file (image or STEP). """ try: file_path = generate_apdl_script(cad_file, element_type, material_ex, material_nu) return file_path except ValueError as e: return str(e) # Gradio Input and Output for CAD File Upload iface = gr.Interface( fn=generate_script_ui_from_cad, inputs=[ gr.File(label="Upload CAD File (Image or STEP)"), gr.Textbox(label="Element Type (e.g., SOLID186)", value="SOLID186"), gr.Number(label="Material EX (Young's Modulus)", value=200e9), gr.Number(label="Material NU (Poisson's Ratio)", value=0.3), ], outputs=gr.File(label="Generated APDL Script"), title="APDL Script Generator from CAD File", description="Upload a CAD file (2D image or STEP format) and provide material properties to generate an APDL script." ) # Launch the Interface iface.launch()