Spaces:
Build error
Build error
Create core_processor.py
Browse files- core_processor.py +143 -0
core_processor.py
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import cv2
|
| 2 |
+
import numpy as np
|
| 3 |
+
import potrace
|
| 4 |
+
import svgpathtools
|
| 5 |
+
import ezdxf
|
| 6 |
+
from ezdxf.addons.dxf2svg import make_svg
|
| 7 |
+
import trimesh
|
| 8 |
+
import io
|
| 9 |
+
import base64
|
| 10 |
+
|
| 11 |
+
class SculptorEngine:
|
| 12 |
+
def __init__(self):
|
| 13 |
+
pass
|
| 14 |
+
|
| 15 |
+
def preprocess_for_cnc(self, image):
|
| 16 |
+
"""
|
| 17 |
+
Sculptok style cleanup: Remove noise, sharpen edges, high contrast.
|
| 18 |
+
"""
|
| 19 |
+
# Grayscale
|
| 20 |
+
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
| 21 |
+
|
| 22 |
+
# Bilateral Filter: Noise remove karta hai but edges preserve rakhta hai
|
| 23 |
+
# (Ye manual tracing jaisa clean look deta hai)
|
| 24 |
+
clean = cv2.bilateralFilter(gray, 9, 75, 75)
|
| 25 |
+
|
| 26 |
+
# Adaptive Threshold: Har jagah alag lighting ke hisab se lines nikalta hai
|
| 27 |
+
thresh = cv2.adaptiveThreshold(
|
| 28 |
+
clean, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
|
| 29 |
+
cv2.THRESH_BINARY, 11, 2
|
| 30 |
+
)
|
| 31 |
+
|
| 32 |
+
# Invert colors (Potrace ko black bg pe white lines chahiye)
|
| 33 |
+
inverted = cv2.bitwise_not(thresh)
|
| 34 |
+
return inverted
|
| 35 |
+
|
| 36 |
+
def generate_vector(self, image_path):
|
| 37 |
+
"""
|
| 38 |
+
Potrace engine use karke High-Resolution SVG banata hai.
|
| 39 |
+
"""
|
| 40 |
+
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
|
| 41 |
+
processed = self.preprocess_for_cnc(cv2.cvtColor(img, cv2.COLOR_GRAY2BGR))
|
| 42 |
+
|
| 43 |
+
# Potrace Bitmap object
|
| 44 |
+
bmp = potrace.Bitmap(processed)
|
| 45 |
+
path = bmp.trace()
|
| 46 |
+
|
| 47 |
+
# SVG Header
|
| 48 |
+
w, h = processed.shape[1], processed.shape[0]
|
| 49 |
+
svg_header = f'<svg width="{w}" height="{h}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {w} {h}">'
|
| 50 |
+
svg_paths = ""
|
| 51 |
+
|
| 52 |
+
# Potrace se path data nikalna
|
| 53 |
+
for curve in path:
|
| 54 |
+
for segment in curve:
|
| 55 |
+
# Start point
|
| 56 |
+
start_node = segment.start_point
|
| 57 |
+
d = f"M {start_node.x} {start_node.y} "
|
| 58 |
+
|
| 59 |
+
# Cubic Bezier curves
|
| 60 |
+
for c in segment:
|
| 61 |
+
d += f"C {c.c1.x} {c.c1.y}, {c.c2.x} {c.c2.y}, {c.end_point.x} {c.end_point.y} "
|
| 62 |
+
|
| 63 |
+
d += "Z " # Close path
|
| 64 |
+
svg_paths += f'<path d="{d}" fill="none" stroke="black" stroke-width="1" vector-effect="non-scaling-stroke"/>'
|
| 65 |
+
|
| 66 |
+
svg_output = svg_header + svg_paths + "</svg>"
|
| 67 |
+
|
| 68 |
+
# SVG file save
|
| 69 |
+
svg_file = "/tmp/result.svg"
|
| 70 |
+
with open(svg_file, "w") as f:
|
| 71 |
+
f.write(svg_output)
|
| 72 |
+
|
| 73 |
+
return svg_file
|
| 74 |
+
|
| 75 |
+
def generate_dxf(self, svg_file_path):
|
| 76 |
+
"""
|
| 77 |
+
SVG paths ko DXF (CAD format) mein convert karta hai.
|
| 78 |
+
"""
|
| 79 |
+
paths, _ = svgpathtools.svg2paths(svg_file_path)
|
| 80 |
+
|
| 81 |
+
doc = ezdxf.new('R2010')
|
| 82 |
+
msp = doc.modelspace()
|
| 83 |
+
|
| 84 |
+
for path in paths:
|
| 85 |
+
for segment in path:
|
| 86 |
+
if isinstance(segment, svgpathtools.Line):
|
| 87 |
+
start = segment.start.real, segment.start.imag
|
| 88 |
+
end = segment.end.real, segment.end.imag
|
| 89 |
+
msp.add_line(start, end)
|
| 90 |
+
elif isinstance(segment, svgpathtools.CubicBezier):
|
| 91 |
+
control1 = segment.control1.real, segment.control1.imag
|
| 92 |
+
control2 = segment.control2.real, segment.control2.imag
|
| 93 |
+
end = segment.end.real, segment.end.imag
|
| 94 |
+
start = segment.start.real, segment.start.imag
|
| 95 |
+
msp.add_spline(
|
| 96 |
+
control_points=[(start[0], start[1]), (control1[0], control1[1]), (control2[0], control2[1]), (end[0], end[1])],
|
| 97 |
+
degree=3
|
| 98 |
+
)
|
| 99 |
+
|
| 100 |
+
dxf_file = "/tmp/result.dxf"
|
| 101 |
+
doc.saveas(dxf_file)
|
| 102 |
+
return dxf_file
|
| 103 |
+
|
| 104 |
+
def generate_3d_relief(self, image, model):
|
| 105 |
+
"""
|
| 106 |
+
Image ko 3D Depth Map mein convert karta hai (AI wala kaam).
|
| 107 |
+
"""
|
| 108 |
+
# AI Model se Depth Prediction
|
| 109 |
+
depth_map = model(image)
|
| 110 |
+
|
| 111 |
+
# Normalize depth map
|
| 112 |
+
depth_map = np.array(depth_map)
|
| 113 |
+
depth_map = (depth_map - depth_map.min()) / (depth_map.max() - depth_map.min())
|
| 114 |
+
|
| 115 |
+
# Mesh Generation (Basic logic for demo, production mein Marching Cubes use hota)
|
| 116 |
+
# Simple plane mesh with displacement
|
| 117 |
+
h, w = depth_map.shape
|
| 118 |
+
vertices = []
|
| 119 |
+
faces = []
|
| 120 |
+
|
| 121 |
+
# Scale down for performance in demo
|
| 122 |
+
scale = 0.1
|
| 123 |
+
|
| 124 |
+
for y in range(h):
|
| 125 |
+
for x in range(w):
|
| 126 |
+
z = depth_map[y, x] * 10 # Height multiplier
|
| 127 |
+
vertices.append([x * scale, y * scale, z])
|
| 128 |
+
|
| 129 |
+
# Create faces (Grid mesh)
|
| 130 |
+
for y in range(h - 1):
|
| 131 |
+
for x in range(w - 1):
|
| 132 |
+
v1 = y * w + x
|
| 133 |
+
v2 = y * w + (x + 1)
|
| 134 |
+
v3 = (y + 1) * w + x
|
| 135 |
+
v4 = (y + 1) * w + (x + 1)
|
| 136 |
+
faces.append([v1, v2, v3])
|
| 137 |
+
faces.append([v2, v4, v3])
|
| 138 |
+
|
| 139 |
+
mesh = trimesh.Trimesh(vertices=vertices, faces=faces)
|
| 140 |
+
|
| 141 |
+
stl_file = "/tmp/result.stl"
|
| 142 |
+
mesh.export(stl_file)
|
| 143 |
+
return stl_file
|