Initial commit
This commit is contained in:
84
pcb_to_stl.py
Normal file
84
pcb_to_stl.py
Normal file
@@ -0,0 +1,84 @@
|
||||
import bpy
|
||||
import sys
|
||||
import os
|
||||
|
||||
# --- Parse Arguments ---
|
||||
# structure: [..., 'input.svg', 'output.stl', 'thickness', 'width']
|
||||
try:
|
||||
argv = sys.argv
|
||||
argv = argv[argv.index("--") + 1:]
|
||||
|
||||
input_svg = argv[0]
|
||||
output_stl = argv[1]
|
||||
thickness_mm = float(argv[2])
|
||||
target_width_mm = float(argv[3])
|
||||
except (ValueError, IndexError) as e:
|
||||
print(f"Error parsing arguments: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
# --- Step 1: Clean & Setup Units ---
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
|
||||
scene = bpy.context.scene
|
||||
scene.unit_settings.system = 'METRIC'
|
||||
scene.unit_settings.length_unit = 'MILLIMETERS'
|
||||
# This scale allows us to work in mm directly (1.0 = 1mm)
|
||||
scene.unit_settings.scale_length = 0.001
|
||||
|
||||
# --- Step 2: Import SVG ---
|
||||
if not os.path.exists(input_svg):
|
||||
print(f"FATAL: File not found: {input_svg}")
|
||||
sys.exit(1)
|
||||
|
||||
bpy.ops.import_curve.svg(filepath=input_svg)
|
||||
|
||||
# --- Step 3: Geometry Processing ---
|
||||
bpy.ops.object.select_all(action='SELECT')
|
||||
|
||||
if bpy.context.selected_objects:
|
||||
# Set active object
|
||||
bpy.context.view_layer.objects.active = bpy.context.selected_objects[0]
|
||||
|
||||
# 1. Join all parts into one
|
||||
bpy.ops.object.join()
|
||||
obj = bpy.context.active_object
|
||||
|
||||
# 2. Convert to Mesh (Flat 2D)
|
||||
bpy.ops.object.convert(target='MESH')
|
||||
|
||||
# --- Step 3.5: RESIZE TO TARGET WIDTH (MM) ---
|
||||
if target_width_mm > 0:
|
||||
# Get current width (X dimension)
|
||||
current_width = obj.dimensions.x
|
||||
|
||||
if current_width > 0.000001:
|
||||
scale_factor = target_width_mm / current_width
|
||||
print(f"Resizing: {current_width:.2f}mm -> {target_width_mm:.2f}mm (Factor: {scale_factor:.4f})")
|
||||
|
||||
# Apply Scale to X and Y (Maintain Aspect Ratio)
|
||||
# We do NOT scale Z because Z is 0 (flat mesh)
|
||||
obj.scale[0] = scale_factor
|
||||
obj.scale[1] = scale_factor
|
||||
|
||||
# Freeze the scale transformation so dimensions are real
|
||||
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
|
||||
else:
|
||||
print("Warning: Object has 0 width, skipping resize.")
|
||||
|
||||
# 3. Extrude (Z-Height)
|
||||
# Now that X/Y are sized correctly, we extrude Z
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
bpy.ops.mesh.select_all(action='SELECT')
|
||||
|
||||
# Extrude exactly the thickness value
|
||||
bpy.ops.mesh.extrude_region_move(TRANSFORM_OT_translate={"value":(0, 0, thickness_mm)})
|
||||
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
# --- Step 4: Export STL ---
|
||||
print(f"Exporting to: {output_stl}")
|
||||
bpy.ops.wm.stl_export(filepath=output_stl, global_scale=1.0)
|
||||
|
||||
else:
|
||||
print("Error: No objects found in SVG.")
|
||||
sys.exit(1)
|
||||
Reference in New Issue
Block a user