Speaker Grille from Bitmap Image

Speaker Grille from Bitmap Image

Compatible with WizoScript 3.00 and later.

This script takes an image and looks for the black pixels. It then creates a set of holes in the same pattern as the black pixels.

from __future__ import division

# get access to library in Windows for using images
import clr
clr.AddReference("System.Drawing")
from System.Drawing import Image

ScriptName = "Speaker Grille"

# create a dialog window to allow user to select image and where grille will go
Win = Windows()
Options = []
Options.append(["Image", WindowsInputTypes.File, None])
Options.append(["Face for Grille", WindowsInputTypes.Face, None])
Options.append(["Grille Center Point", WindowsInputTypes.Point, None])
Options.append(["Grille Width (mm)", WindowsInputTypes.Real, 100])
Options.append(["Grille Height (mm)", WindowsInputTypes.Real, 100])
Options.append(["Hole Diameter (mm)", WindowsInputTypes.Real, 4])
Options.append(["Cut Depth (mm)", WindowsInputTypes.Real, 5])
Options.append(["Reverse Cut", WindowsInputTypes.Boolean, False])

# check for cancel
Values = Win.OptionsDialog(ScriptName, Options)
if Values == None:
  sys.exit()

# get path and name of image file
ImageFile = Values[0]
if ImageFile == None or not ImageFile:
  Win.ErrorDialog("No image selected", ScriptName)
  sys.exit()

# get face in part
GrilleFace = Values[1]
if GrilleFace == None:
  Win.ErrorDialog("No face selected", ScriptName)
  sys.exit()

# get center point
CenterPoint = Values[2]
if CenterPoint == None:
  Win.ErrorDialog("No center point selected", ScriptName)
  sys.exit()

# get dimensions
Width = Values[3]
if Width == 0:
  Win.ErrorDialog("Invalid width", ScriptName)
  sys.exit()
Height = Values[4]
if Height == 0:
  Win.ErrorDialog("Invalid height", ScriptName)
  sys.exit()
  
# get hole diameter
HoleDiameter = Values[5]
if HoleDiameter == 0:
  Win.ErrorDialog("Invalid hole diameter", ScriptName)
  sys.exit()

# get cut depth
CutDepth = Values[6]
if CutDepth == 0:
  Win.ErrorDialog("Invalid cut depth", ScriptName)
  sys.exit()
  
# get reverse cut
ReverseCut = Values[7]

# get locations of all the black pixels in the image
# the origin of the image is top left but the origin of the sketch
# will be bottom left so we need to flip the points
Points = []
Img = Image.FromFile(ImageFile)
for x in range(Img.Width):
  for y in range(Img.Height):
    Pixel = Img.GetPixel(x, y)
    # A = alpha channel aka transparency, 255 = opaque
    if Pixel.A == 255 and Pixel.R == 0 and Pixel.G == 0 and Pixel.B == 0:
      y = Img.Height - y - 1
      Points.append([x, y])

# scale points
ScaleX = Width / Img.Width
ScaleY = Height / Img.Height
for P in Points:
  P[0] = P[0] * ScaleX
  P[1] = P[1] * ScaleY

# get scaled size
ScaledWidth = Img.Width * ScaleX
ScaledHeight = Img.Height * ScaleY

# get the part we are editing
Prt = GrilleFace.GetPart()

# create sketch and project center point onto sketch
Sk = Prt.AddSketch("Grille", GrilleFace)
Center = CenterPoint.GetCoordinates()
[cx, cy] = Sk.GlobaltoPoint(Center[0], Center[1], Center[2])

# center points
for P in Points:
  P[0] = P[0] - (ScaledWidth / 2) + cx
  P[1] = P[1] - (ScaledHeight / 2) + cy

# draw holes
Sk.AutomaticStartEndEditing = False
Sk.StartEditing()
for P in Points:
  Sk.AddCircle(P[0], P[1], HoleDiameter, False)
Sk.StopEditing()
Sk.AutomaticStartEndEditing = True

# cut holes
Prt.AddExtrudeCut("Grille", Sk, CutDepth, ReverseCut)

Leave a Reply

Your email address will not be published. Required fields are marked *