Browsed by
Tag: windows

Equation Sketcher

Equation Sketcher

Compatible with WizoScript 3.00 and later.

Enter a formula and a Bspline is added to your chosen sketch with the mathematical shape. X and Y can be swapped if needed. The number of points for calculation is controllable. The start of the line is offset to begin at a node manually placed on the sketch before running the script.

from __future__ import division
from math import sqrt

Win = Windows()

ScriptName = "Equation Sketch"

Options = []
Options.append([None, WindowsInputTypes.Label, "The sketch must have a node added already that marks the start of the line"])
Options.append(["Equation y = ", WindowsInputTypes.String, "0.1*x**2"])
Options.append(["Sketch", WindowsInputTypes.Sketch, None])
Options.append(["Start X (at node)", WindowsInputTypes.Real, 0])
Options.append(["End X", WindowsInputTypes.Real, 10])
Options.append(["Number of points", WindowsInputTypes.Integer, 10])
Options.append(["Swap X and Y", WindowsInputTypes.Boolean, False])

Values = Win.OptionsDialog(ScriptName, Options)
if Values == None:
  sys.exit()

# get the inputs
Equation = Values[0]
Sk = Values[1]
StartX = Values[2]
EndX = Values[3]
NumPoints = Values[4]
SwapXY = Values[5]

# validate
if not Equation:
  Win.ErrorDialog("No equation entered", ScriptName)
  sys.exit()
if Sk == None:
  Win.ErrorDialog("No sketch selected", ScriptName)
  sys.exit()
if StartX > EndX:
  Win.ErrorDialog("Start X value is greater than end X value", ScriptName)
  sys.exit()
if NumPoints < 2:
  Win.ErrorDialog("Invalid number of points", ScriptName)
  sys.exit()

# get the part that defines the sketch
Prt = Sk.GetPart()

# check sketch defines a node
# we assume first sketch figure is the node
if len(Sk.Figures) == 0:
  Win.ErrorDialog("The sketch doesn't have a node defined", ScriptName)
  sys.exit()
if isinstance(Sk.Figures[0], SketchPoint) == False:
  Win.ErrorDialog("Can't find node on sketch", ScriptName)
  sys.exit()

# get location of node
NodeX = Sk.Figures[0].X
NodeY = Sk.Figures[0].Y

# we only import this now because it can cause a bit of a delay
from sympy import *

# parse equation
x = Symbol("x")
Eq = sympify(Equation)

# work out how much we increase x between points
StepX = (EndX - StartX) / NumPoints

# calculate the points
Points = []
ValX = StartX
for p in xrange(NumPoints):
  ValY = Eq.subs(x, ValX)
  if SwapXY == True:
    PY = ValX
    PX = ValY
  else:
    PX = ValX
    PY = ValY
  Points.extend([float(PX + NodeX), float(PY + NodeY)])
  ValX = ValX + StepX

# generate the bspline
Sk.AddBsplineThroughPoints(3, Points, False)
Cylinder Between Two Points II

Cylinder Between Two Points II

Compatible with WizoScript 3.00 and later.

Inserts a cylinder between two points.

from math import sqrt

Win = Windows()

Options = []
Options.append(["Start Point", WindowsInputTypes.Point, None])
Options.append(["End Point", WindowsInputTypes.Point, None])
Options.append(["Diameter", WindowsInputTypes.Real, 5])

Values = Win.OptionsDialog("Cylinder", Options)
if Values == None:
  sys.exit()
if Values[0] == None:
  Win.ErrorDialog("No start point selected", "Cylinder")
  sys.exit()
if Values[1] == None:
  Win.ErrorDialog("No end point selected", "Cylinder")
  sys.exit()
if Values[2] <= 0:
  Win.ErrorDialog("Invalid diameter", "Cylinder")
  sys.exit()

# get the part that defines the first point
# it is possible the second point is on a different part but we will assume
# they are on the same part
P = Values[0].GetPart()

# get points and diameter
cyl_p1 = Values[0].GetCoordinates()
cyl_p2 = Values[1].GetCoordinates()
diameter = Values[2]

# get length of cynlinder using euclidean distance
length = sqrt((cyl_p2[0] - cyl_p1[0])**2 + (cyl_p2[1] - cyl_p1[1])**2 + (cyl_p2[2] - cyl_p1[2])**2)
 
# calculate normal vector for the plane at the first end of the cylinder
normal_vector = [cyl_p2[0] - cyl_p1[0], cyl_p2[1] - cyl_p1[1], cyl_p2[2] - cyl_p1[2]]
 
# create plane for one end of the cylinder
cyl_plane = P.AddPlane("Cyl Start Plane", normal_vector, cyl_p1)
 
P.AddAxis("Cylinder Axis", cyl_p1, cyl_p2)
 
# draw a circle on the plane
S = P.AddSketch("Cylinder End", cyl_plane)
[cx, cy] = S.GlobaltoPoint(cyl_p1[0], cyl_p1[1], cyl_p1[2])
S.AddCircle(cx, cy, diameter, False)
 
# extrude into a cylinder
P.AddExtrudeBoss("Cylinder", S, length, True)
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)
Useful Dialogs

Useful Dialogs

Compatible with WizoScript versions: 2.65

Demonstrates how to show information, error and question dialogs.

Win = Windows()
 
Win.InfoDialog("I am about to create a part", "My Script")
 
Win.ErrorDialog("Oops. That didn't go as planned", "My Script")
 
# returns True for 'yes' and False for 'no'
print Win.QuestionDialog("Shall I stop?", "My Script")
Wave Washer

Wave Washer

Compatible with WizoScript versions: 2.60

Generates wave washers. Uses a custom dialog window. Requires Geomagic Design V18 (2015.1.0) or later.

import math
from math import *
 
# radius
R = 100.0
# amplitude
A = 10.0
# number of waves (must be a whole number)
B = 4
 
# width
Width = 10
# thickness
Thickness = 5
 
Win = Windows()
 
Options = []
Options.append(["Radius", WindowsInputTypes.Real, R])
Options.append(["Amplitude", WindowsInputTypes.Real, A])
Options.append(["Number of Waves", WindowsInputTypes.Integer, B])
Options.append(["Width", WindowsInputTypes.Real, Width])
Options.append(["Thickness", WindowsInputTypes.Real, Thickness])
 
Values = Win.OptionsDialog("Wave Washer Generator", Options)
if Values == None:
  sys.exit()
 
R = Values[0]
A = Values[1]
B = Values[2]
Width = Values[3]
Thickness = Values[4]
 
# path accuracy = lower number = more points calculated
t_step = 0.1
 
# complete circle = PI x 2
t_max = 3.141592 * 2
 
# keep track of the total points we have calculated
TotalPoints = 0
 
# calculate points for 3D sketch
PathPoints = []
t = 0
while True:
  X = R * sin(t)
  Y = R * cos(t)
  Z = A * sin(B * t)
  PathPoints.extend([X, Y, Z])
  
  if TotalPoints == 0:
    P1 = [X, Y, Z]
  elif TotalPoints == 1:
    P2 = [X, Y, Z]
 
  t = t + t_step
  TotalPoints = TotalPoints + 1
  if t >= t_max:
    break
 
# close path
PathPoints.extend([PathPoints[0], PathPoints[1], PathPoints[2]])
 
# create part and add 3d sketch
P = Part("Wave Washer")
Path = P.Add3DSketch("Path")
Path.AddBspline(PathPoints)
 
# calculate normal vector for the plane at the start of the path
normal_vector = [P2[0] - P1[0], P2[1] - P1[1], P2[2] - P1[2]]
 
# create plane at the start of the path
Plane = P.AddPlane("Start Plane", normal_vector, P1)
 
CrossSection = P.AddSketch("Cross Section", Plane)
 
Origin = CrossSection.GlobaltoPoint(P1[0], P1[1], P1[2])
 
CrossSection.AddRectangle(Origin[0] - (Thickness / 2.0), Origin[1] - (Width / 2.0), Origin[0] + (Thickness / 2.0), Origin[1] + (Width / 2.0), False)
 
P.AddSweepBoss("Washer", CrossSection, Path, False, Part.EndCondition.EntirePath, None, 0, 0, False)
Everyone Loves a Slinky

Everyone Loves a Slinky

Compatible with WizoScript versions: 2.51

Demonstrates how to create a spiral spring. Uses a custom dialog window to get input parameters.

# Everyone Loves a Slinky
# Adapted from:
# http://forum.alibre.com/viewtopic.php?f=9&t=5752&p=30750&hilit=Spring#p30750
 
import sys
import math
 
# create dialog window
Win = Windows()
Options = []
Options.append(["Angle Increment", WindowsInputTypes.Real, 0.05])
Options.append(["Loop Scale", WindowsInputTypes.Real, 0.8])
Options.append(["Height Scale", WindowsInputTypes.Real, 1.0])
Options.append(["Major Helix Width Scale", WindowsInputTypes.Real, 2.0])
Options.append(["Turn Density", WindowsInputTypes.Integer, 25])
 
# show dialog window and get values
Values = Win.OptionsDialog("Everyone Loves a Slinky", Options)
if Values == None:
  sys.exit("User cancelled")
 
AngleIncrement = Values[0]
LoopScale = Values[1]
HeightScale = Values[2]
WidthScale = Values[3]
TurnDensity = Values[4]
print "Angle Increment = %f" % AngleIncrement
print "Loop Scale = %f" % LoopScale
print "Height Scale = %f" % HeightScale
print "Width Scale = %f" % WidthScale
print "Turn Density = %d" % TurnDensity
 
# create list of points for 3d sketch
Points = []
Angle = 0.0
for Pass in range(0, 437):
  X = (WidthScale + LoopScale * math.cos(Angle * TurnDensity)) * math.cos(Angle)
  Y = (WidthScale + LoopScale * math.cos(Angle * TurnDensity)) * math.sin(Angle)
  Z = HeightScale * Angle + LoopScale * math.sin(Angle * TurnDensity)
  Points.extend([X, Y, Z])
  Angle += AngleIncrement
 
# create part and add 3d sketch
Slinky = Part("Slinky")
Path = Slinky.Add3DSketch("Path")
Path.AddBspline(Points)
Custom Values and Settings Window

Custom Values and Settings Window

Compatible with WizoScript versions: 2.50

Shows how to create a custom dialog window that prompts the user to enter values and settings. Supports inputs are: integer, real (float), checkbox and text.

# create windows object
Win = Windows()
 
# construct list of items for the window
Options = []
# ask user for text
Options.append(["Name of the item", WindowsInputTypes.String, "Baz"])
# ask user for a floating point (real) value
Options.append(["Scale", WindowsInputTypes.Real, 1.234])
# checkbox
Options.append(["Enabled", WindowsInputTypes.Boolean, True])
# ask user for an integer
Options.append(["Count", WindowsInputTypes.Integer, 123456])
 
# show window and output results
# if user closes window or clicks on Cancel button then Values will be set to 'None'
Values = Win.OptionsDialog("Test", Options)
print Values
Prompt User to Open or Save a File

Prompt User to Open or Save a File

Compatible with WizoScript versions: 1.99

Shows how to ask the user to choose a file to be opened by the script, or select a folder and name for a file to be saved by the script

Win = Windows()
 
# show open dialog window, if user clicks on OK then a path and filename will be returned
# if user clicks on Cancel then an empty string will be returned
FileName = Win.OpenFileDialog("Select a part file", "Part Files|*.AD_PRT")
print FileName
# if a filename was returned then here is where we would open the file and read the contents
 
# show save dialog window, if user clicks on OK then a path a filename will be returned
# if user clicks on Cancel then an empty string will be returned
FileName = Win.SaveFileDialog("Save a part file", "Part Files|*.AD_PRT")
print FileName
# if a filename was returned then here is where we would create the file and store the contents