Introduction to 3D Modeling. Section 5. Primer in Python Programming
5 Primer in Python Programming
In order to take full advantage of PLaSM, one should learn more about the Python programming language. This primer will give you a useful basic information. If you are interested in computer programming, NCLab provides a comprehensive course that includes a textbook, interactive exercises, review questions, and solution manual.
5.1 Defining and using variables
We learned before that it is a good habit to make our designs parametric. This allows us to adjust them easily any time. Designs that use parameters (variables) rather than raw numbers also tend to be more elegant and less prone to mistakes.
To illustrate this, let us create a 3D model of a pill that is formed by a cylinder with radius
3.0 mm and height 10.0 mm, that ends at both sides with a spherical cap. Moreover the pill
has two colors – one half is red and one half blue. Of course this can be done as
follows:
c2 = COPY(c1)
MOVE(c2, 0, 0, 5.0)
s1 = SPHERE(3.0)
s2 = COPY(s1)
MOVE(s1, 0, 0, 10.0)
half_1 = UNION(c1, s1)
half_2 = UNION(c2, s2)
COLOR(half_1, RED)
COLOR(half_2, BLUE)
SHOW(half_1, half_2)
This is a "brute force" approach which does not use any parameters. The result shown in Fig. 90 is correct.
But imagine that we need to change the length of the base cylinder from 10.0 mm to 12.0 mm. We have to make changes on lines 1, 2, and 4 – so there are at least three places where a mistake can easily be made.
The design can be made safer by using variables. Let us define variables r and h on the
first two lines, and then use them instead of raw numbers:
h = 10.0
c1 = CYL(r, h / 2.0)
c2 = COPY(c1)
MOVE(c2, 0, 0, h / 2.0)
s1 = SPHERE(r)
s2 = COPY(s1)
MOVE(s2, 0, 0, h)
half_1 = UNION(c1, s1)
half_2 = UNION(c2, s2)
COLOR(half_1, RED)
COLOR(half_2, BLUE)
SHOW(half_1, half_2)
Not counting the first two lines, this script has the same length as the previous one. But, any change of the pill’s dimensions is now effortless. No need to study the program and make changes at several places - it is enough to change the values of r and h at the beginning of the program.
5.2 The Numpy library
Python comes with powerful computational libraries that we can use for our PLaSM designs.
In particular, Numpy (numerical computations library) contains vast functionality related to
mathematical functions and numerical computations. Whenever we want to use some
constant such as π or e, or when we want to use some mathematical function such as log(x),
sin(x) or , we import it from Numpy:
We can also import everything using the asterisk symbol ’*’:
Applications of the Numpy library will be shown in the examples at the end of this section.
5.3 Python lists
Whenever we need to create a set of objects, such as a set of points, we can use a Python list
for that. Empty Python list is created using a pair of square brackets:
Here, L is the name of the list, and any other name would be fine as well, as long as it does
not clash with some Python or PLaSM command. We can also create a nonempty list. Say
that we need a list that contains the points (0, 0), (1, 0), (0, 1). This can be done as
follows:
You are right, each point is a list as well! Sometimes we need to fill a list using some
procedure because not all its items are known at the beginning. For this, we can use the
command append(). For example, the point (2, 4) can be added to the existing list L
via
Python provides a number of useful operations with lists including inserting an item at an arbitrary position, deleting an item from an arbitrary position, reversing and sorting lists, merging lists, counting occurences of some item, etc. These are beyond our primer but you can find them in the NCLab Python textbook.
5.4 Printing
Control prints are a practical way to check that all values are as they should be. Printing is
done via the print command. For example, the script
print L
has the following output:
Printing the value of a single variable is done in the same way, and we can make the output
more informative by actually describing what is printed. The script
print ~h =~, h
yields the following output:
5.5 Loops
Let us mention one last scripting technique for now, which is to repeat some command or
sequence of commands several times. To repeat something N times, we use the following
construct:
do_something
The indentation matters as it indicates the body of the loop (set of commands to be repeated).
For example, the following script will print a sequence of integers between 0 and 5 (not
including 5):
print i
Output:
1
2
3
4
Once more – notice that the printed sequence ends with 4, not with 5. This is a common source of beginner’s mistakes.
Let us show one more example of how repetition can be used: We will create a list of
points (0, 0), (1, 0), (2, 0), ..., (N, 0) where N is some positive integer. Let us write the script
initially for N = 5, and at the end we will print it:
L = []
for i in range(N+1):
L.append([i, 0])
print ~L =~, L
Output:
If we needed to create another list for N = 100, the script would remain the same, just the
line where N is defined would be changed to
Scripting can save lots of work! Let us practice our scripting skills on some simple examples.
5.6 Example 1 - programming a polygon
First we will generate a polygon with N equally-long edges that is inscribed in a circle with
radius R. Notice that the points (R cos(a),R sin(a)) where a is an angle between 0 and 2π, lie
on the circle with center (0, 0) and radius R. We begin with importing the sine and cosine
fundtions, and the number π from Numpy:
Next create a variable R for the radius and N for the number of edges:
R = 5
Now the scripting part comes: We create an empty list points, and in a loop append the N
points that lie on the circle:
for i in range(N):
a = i * 2. * pi / N
points.append([R * cos(a), R * sin(a)])
poly = CHULL(points)
Note the asterisk ’*’ in front of the list points on the last line. Its purpose is to "take the
square brackets off the list" – decompose the list points into a sequence of its entries as
expected by the CHULL command.
Finally, let us view the polygon poly in copper color:
SHOW(poly)
The result is displayed in Fig. 91.
5.7 Example 2 - programming a cone
Next let us tweak the above script to construct a cone with radius R and height H. All we need
to do is to add a zero third coordinate to all points and add one more point for the apex. The
CHULL command will take care of the rest. Since the script is so similar to the last one, it is not
necessary to comment all steps in detail:
R = 5
H = 10
subdiv = 128
The only other thing worth mentioning is the parameter subdiv that plays the role of N from
the previous script – in fact this is the optional third parameter of the CONE command!
The list of 3D points forming the cone is created as follows:
for i in range(subdiv):
angle = i * 2. * pi / subdiv
points.append([R * cos(angle), R * sin(angle), 0])
points.append([0, 0, H])
c = CHULL(points)
Finally, let us view the polygon poly in copper color:
SHOW(c)
The result is displayed in Fig. 92.
5.8 Example 3 - programming arrays of objects
In this example, we will create a field of 400 cylindrical poles. Certainly this is something that
we would like to do manually. Here is a script that does it for us:
c = CYL(0.1, 1, 16)
N = 20
# Duplicate the cylinder N^2 times:
columns = []
for i in range(N):
for j in range(N):
d = COPY(c)
MOVE(d, i, j, 0)
columns.append(d)
# View the result:
SHOW(columns)
The result for N = 20, which means 400 columns, is shown in Fig. 93.
More columns? By changing N to 50 and running the script again, we instantly create 2,500 of them: