SculptOkPro / core_processor.py
TS447's picture
Create core_processor.py
c421e99 verified
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 width="{w}" height="{h}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {w} {h}">'
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'<path d="{d}" fill="none" stroke="black" stroke-width="1" vector-effect="non-scaling-stroke"/>'
svg_output = svg_header + svg_paths + "</svg>"
# 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