Browsed by
Tag: 2D

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:

# 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)
if Sk == None:
  Win.ErrorDialog("No sketch selected", ScriptName)
if StartX > EndX:
  Win.ErrorDialog("Start X value is greater than end X value", ScriptName)
if NumPoints < 2:
  Win.ErrorDialog("Invalid number of points", ScriptName)

# 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)
if isinstance(Sk.Figures[0], SketchPoint) == False:
  Win.ErrorDialog("Can't find node on sketch", ScriptName)

# 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
    PX = ValX
    PY = ValY
  Points.extend([float(PX + NodeX), float(PY + NodeY)])
  ValX = ValX + StepX

# generate the bspline
Sk.AddBsplineThroughPoints(3, Points, False)
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
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:

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

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

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

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

# get cut depth
CutDepth = Values[6]
if CutDepth == 0:
  Win.ErrorDialog("Invalid cut depth", ScriptName)
# 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
for P in Points:
  Sk.AddCircle(P[0], P[1], HoleDiameter, False)
Sk.AutomaticStartEndEditing = True

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

Polygon Incircle

Compatible with WizoScript versions: 2.51

Polygons in Geomagic Design can be defined by an “exterior” or “interior” circle. The interior circle is typically used for bolt heads. The circle is called an “incircle”. This script shows how to draw a polygon by defining the incircle diameter.

import math
# diameter of circle that fits inside polygon
Diameter = 100
# number of sides
Sides = 6
# calculate exterior diameter of polygon
EDia = Diameter / math.cos(math.pi / Sides)
# create part, create polygon sketch, extrude
P = Part("Hex")
S = P.AddSketch("Hexagon", P.GetPlane("XY-Plane"))
S.AddPolygon(0, 0, EDia, Sides, False)
P.AddExtrudeBoss("Hex Head", S, 10, False)


Compatible with WizoScript versions: 2.51

Simple sketch of a triangle with angles 90, 15, 75 degrees.

# Create triangle with angles 90, 15, 75
import math
# set up parameters
Theta = 15.0
Adjacent = 100.0
# calculate side
Opposite = Adjacent * math.tan(math.radians(15.0))
# generate three vertices of triangle
P1_X = 0
P1_Y = 0
P2_X = Adjacent
P2_Y = 0
P3_X = Adjacent
P3_Y = Opposite
# create part and sketch
P = Part("Foo")
S = P.AddSketch("Shape", P.GetPlane("XY-Plane"))
# draw it
S.AddLine(P1_X, P1_Y, P2_X, P2_Y, False)
S.AddLine(P2_X, P2_Y, P3_X, P3_Y, False)
S.AddLine(P3_X, P3_Y, P1_X, P1_Y, False)
Slice a Part

Slice a Part

Compatible with WizoScript versions: 1.95

Slices a part at a plane called “Slice”

# open part
P = Part(r"P:\temp\GDForum", "Test")
# get bounding box of part - eight points, one for each corner
# of the bounding box
Bounds = P.GetBoundingBox()
# get the plane that the part will be sliced on
SlicePlane = P.GetPlane("Slice")
# create a sketch on the slicing plane
S = P.AddSketch("SliceSketch", SlicePlane)
# empty list
Proj = []
# for each corner of the part bounding box, map that 3D point into
# a 2D point on the sketch
# this doesn't create the points in the sketch, but is only a mathematical
# operation
for i in range(0, 8):
  Proj.append(S.GlobaltoPoint(Bounds[i][0], Bounds[i][1], Bounds[i][2]))
# go through the eight 2D points and find the maximum and minimum
# X and Y values
MaxX = Proj[0][0]
for i in range (0, 8):
  if Proj[i][0] >= MaxX :
    MaxX = Proj[i][0]
MaxY = Proj[0][1]
for i in range (0, 8):
  if Proj[i][1] >= MaxY :
    MaxY = Proj[i][1]
MinX = Proj[0][0]
for i in range (0, 8):
  if Proj[i][0] < MinX :
    MinX = Proj[i][0]
MinY = Proj[0][1]
for i in range (0, 8):
  if Proj[i][1] < MinY :
    MinY = Proj[i][1]
# draw a rectangle on the sketch which will cover the entire part when viewed
# perpendicular to the slicing plane
S.AddRectangle(MinX, MinY, MaxX, MaxY, False)
# cut the part using the rectangle
P.AddExtrudeCut("Cut", S, 100, False)
Scaling a Sketch

Scaling a Sketch

Compatible with WizoScript versions: 1.70

Creates a copy of a sketch and scales it to 50% in size

Units.Current = UnitTypes.Inches
TestRoom = Part("TEST ROOM Scaled", False)
OriginalSketch = TestRoom.GetSketch("Sketch<2>")
# currently 8.25" wide, need it to be 4.125"
ScaleFactor = 4.125 / 8.25 * 100.0
ScaledSketch = TestRoom.AddSketch("Scaled", TestRoom.GetFace("Face<6>"))
ScaledSketch.CopyFrom(OriginalSketch, 0, 0, 0, 0, 0, 0, 0, ScaleFactor)
Calculating Length of Polylines

Calculating Length of Polylines

Compatible with WizoScript versions: 1.42

This example adds up the total lengths of all lines in a sketch in a part that is already open.

# Calculates the total length of all lines in a sketch
# This script assumes a part called 'Polyline' is already open
# and contains a single sketch called 'Sketch<1>' which has the lines
# to measure
Units.Current = UnitTypes.Millimeters
# get already opened part and then get sketch on part
P = Part("Polyline", False)
S = P.GetSketch("Sketch<1>")
# get total length of all lines in the sketch
TotalLength = 0
for Figure in S.Figures:
  if Figure.IsReference == False:
    TotalLength = TotalLength + Figure.Length
print "Total length of polyline = %.3f mm" % TotalLength
Parabolic Curve

Parabolic Curve

Compatible with WizoScript versions: 1.42

Creates a parabolic curve from 0cm, 0cm to 15cm, 60cm.

# Draws a parabolic curve in a sketch from 0cm,0cm to 15cm,60cm
Units.Current = UnitTypes.Centimeters
# y = ax^2 where x = 15 and y = 60
def para(x):
  y = 0.2666666666 * x**2
  return y
MyPart = Part("My Part")
Parabola = MyPart.AddSketch("Parabola", MyPart.GetPlane("XY-Plane"))
# generate list of points
points = []
for x in range(0, 16):
  points.extend([x, para(x)])
Parabola.AddBsplineThroughPoints(3, points, False)
CSV Import with Point Rotation

CSV Import with Point Rotation

Compatible with WizoScript versions: 1.40

The following script shows how to import a set of 2D points from a CSV file, rotate them about a arbitrary point and then add them to a 2D sketch.

# imports a set of 2D points from a csv file, rotates them and then
# adds them to a 2D sketch with lines connecting the points
# specify which libraries we are going to use
import csv
import math
# configuration
angle = 30.5
rotationpoint = [5.0, 5.0]
csvfile = r"C:\Users\Andy\Example.csv"
# rotates a point around another point
# passed is the angle, the point to rotate and the origin of the rotation
# copied from
def rotate2d(degrees,point,origin):
  x = point[0] - origin[0]
  yorz = point[1] - origin[1]
  newx = (x*math.cos(math.radians(degrees))) - (yorz*math.sin(math.radians(degrees)))
  newyorz = (x*math.sin(math.radians(degrees))) + (yorz*math.cos(math.radians(degrees)))
  newx += origin[0]
  newyorz += origin[1] 
  return newx,newyorz
# list of points, empty for now
# points will be stored as [x1,y1, x2,y2, ... ,xn,yn]
points = []
# open csv file
f = open(csvfile)
# create csv reader and read in lines
reader = csv.reader(f)
for row in reader:
  # column 0 contains x, column 1 contains y
  x = float(row[0])
  y = float(row[1])
  # rotate point and add to list of points
  points.extend(rotate2d(angle, [x, y], rotationpoint))
# finished with csv file
# show number of points found
print "Found %d points" % (len(points) / 2)
# create part
MyPart = Part("My Part")
# add sketch on XY plane
PointSketch = MyPart.AddSketch("Point Sketch", MyPart.GetPlane("XY-Plane"))
# add points with lines connecting them
PointSketch.AddLines(points, False)