import cv2 import numpy as np import potrace import svgpathtools import ezdxf from ezdxf.addons.dxf2svg import make_svg import trimesh import io import base64 class SculptorEngine: def __init__(self): pass def preprocess_for_cnc(self, image): """ Sculptok style cleanup: Remove noise, sharpen edges, high contrast. """ # Grayscale gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Bilateral Filter: Noise remove karta hai but edges preserve rakhta hai # (Ye manual tracing jaisa clean look deta hai) clean = cv2.bilateralFilter(gray, 9, 75, 75) # Adaptive Threshold: Har jagah alag lighting ke hisab se lines nikalta hai thresh = cv2.adaptiveThreshold( clean, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2 ) # Invert colors (Potrace ko black bg pe white lines chahiye) inverted = cv2.bitwise_not(thresh) return inverted def generate_vector(self, image_path): """ Potrace engine use karke High-Resolution SVG banata hai. """ img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) processed = self.preprocess_for_cnc(cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)) # Potrace Bitmap object bmp = potrace.Bitmap(processed) path = bmp.trace() # SVG Header w, h = processed.shape[1], processed.shape[0] svg_header = f'' svg_paths = "" # Potrace se path data nikalna for curve in path: for segment in curve: # Start point start_node = segment.start_point d = f"M {start_node.x} {start_node.y} " # Cubic Bezier curves for c in segment: d += f"C {c.c1.x} {c.c1.y}, {c.c2.x} {c.c2.y}, {c.end_point.x} {c.end_point.y} " d += "Z " # Close path svg_paths += f'' svg_output = svg_header + svg_paths + "" # SVG file save svg_file = "/tmp/result.svg" with open(svg_file, "w") as f: f.write(svg_output) return svg_file def generate_dxf(self, svg_file_path): """ SVG paths ko DXF (CAD format) mein convert karta hai. """ paths, _ = svgpathtools.svg2paths(svg_file_path) doc = ezdxf.new('R2010') msp = doc.modelspace() for path in paths: for segment in path: if isinstance(segment, svgpathtools.Line): start = segment.start.real, segment.start.imag end = segment.end.real, segment.end.imag msp.add_line(start, end) elif isinstance(segment, svgpathtools.CubicBezier): control1 = segment.control1.real, segment.control1.imag control2 = segment.control2.real, segment.control2.imag end = segment.end.real, segment.end.imag start = segment.start.real, segment.start.imag msp.add_spline( control_points=[(start[0], start[1]), (control1[0], control1[1]), (control2[0], control2[1]), (end[0], end[1])], degree=3 ) dxf_file = "/tmp/result.dxf" doc.saveas(dxf_file) return dxf_file def generate_3d_relief(self, image, model): """ Image ko 3D Depth Map mein convert karta hai (AI wala kaam). """ # AI Model se Depth Prediction depth_map = model(image) # Normalize depth map depth_map = np.array(depth_map) depth_map = (depth_map - depth_map.min()) / (depth_map.max() - depth_map.min()) # Mesh Generation (Basic logic for demo, production mein Marching Cubes use hota) # Simple plane mesh with displacement h, w = depth_map.shape vertices = [] faces = [] # Scale down for performance in demo scale = 0.1 for y in range(h): for x in range(w): z = depth_map[y, x] * 10 # Height multiplier vertices.append([x * scale, y * scale, z]) # Create faces (Grid mesh) for y in range(h - 1): for x in range(w - 1): v1 = y * w + x v2 = y * w + (x + 1) v3 = (y + 1) * w + x v4 = (y + 1) * w + (x + 1) faces.append([v1, v2, v3]) faces.append([v2, v4, v3]) mesh = trimesh.Trimesh(vertices=vertices, faces=faces) stl_file = "/tmp/result.stl" mesh.export(stl_file) return stl_file