Blender

Python
Script:
Modifying
a Square Mesh of Polygons
(Part
3): Automating Vertice Creation.


Version
Française
(Note: starting from here, this
text could become unpleasing, and perhaps even: tiresome)
Thus, we have two problems to solve:

we need two nested (one inside the other)
for/next loops in order to construct a two dimensional array, in which
to store our square mesh's vertices.

it is necessary to distribute the elements
contained in the vertice list, which has only one dimension, into a two
dimensional array so that we can locate and recover the vertices of juxtaposed
(adjacent) faces. These faces must form a continuous surface.
For the first problem, Python provides a solution
which consists of temporarily creating, within the limits of the subroutine,
a new list containing all of the necessary values, by using the function:
range(start_value,
end_value, increment_value)
If the starting value is 0, the number
of elements 100 and the increment value 1, range(0, 100, 1) will
build a list, whose value which is stored at index [ 0 ] will be
0, with the index [ 1 ] will be 1, and so on.
If the increment value had been two, it
would have been necessary to write: range(0, 100, 2), the value
stored at [ 0 ] would have been: 0,
in [ 1 ]: 2,
in [ 2 ]: 4,
in [ 3 ]: 6, etc.
# example of a Python loop
for i in range(0, 100, 1):
# The first subroutine
begins here
# with four spaces
of indentation
... 
Note that although the range function returns
integer (whole number) values, when these values are passed to the NMesh.Vert()
function, they will be automatically converted to floating point (decimal)
values before they are saved. This is similiar to when you select the vertex
of a mesh in Edit mode and press 'n' to view the numerical entries of the
selected (active) vertex. If you Shift + Left mouse button click the LocX
numerical entry button, press Shift + [backspace], then enter a value of
0, the integer value 0, is automatically converted to the float value 0.00
. Despite the fact, that most well written functions will do a type check
to ensure that the values entered are in the right format, in some instances,
it is important that you ensure that the number is the correct type, as
we shall discover in Part (4).
For the second problem, it is necessary
to do a little deductive reasoning. Let us imagine for one moment, a square
mesh of polygons made up of 4 faces, with each face having 4 vertices.
Thus, we would have 9 vertices to distribute. Note that although the total
number of vertices is equal to 16, the number of "unique" vertices is less,
since the "faces  to be" share 4 edges where they are joined. For example:
The center vertex is common to all 4 "faces" and therefore has 3 "duplicate"
vertices. The 4 vertices connected to the central vertex also each contain
a duplicate, producing another 4 duplicates for a grand total of 7 duplicates.
Thus, the total number of unique vertices is equal to 16  7 = 9. (Refer
to the sketch below). These vertices are arranged, in a list, in the following
manner: [ 0,1,2,3,4,5,6,7,8 ] . With a quick
sketch, one clearly sees that there are three rows, each consisting of
three vertices. The number of rows could be assigned to a variable "i"
and the number of the vertices in each row could be stored in variable
"j"
.
Or, if you prefer, you could think of
"i" as
the horizontal row number and "j" as the vertical
column number.
The question to ask now is :
What values must be assigned to variables
i
and
j
? (if we have to use both variables to access the first vertex
which is at index 0).
One can postulate:
(i relation j) = 0, the assumption:
(0 relation 0) = 0, looks promising (at least for the first row).
Note that this relationship makes it necessary that both variables i
and
j
start
with a value of zero. For the next index, in the same row, i
continues
to be worth 0, but it is necessary to increase the value of j
to
arrive at 1. The relation could be i +
j,
but
is this always true? In fact, for the following row, i
will
be worth 1, but to arrive at index 3, the relation i +
j will not produce the value that we were hoping for, as j
will
initially be worth 0. For this to succeed, it is necessary to multiply
i
by
3 to obtain the result that we are looking for. The formula which makes
it possible to locate an element in this mesh is i*3+j
.
Is it possible to replace the "magical"
value 3 by a variable which could be determined automatically without
any intervention and according to the total number of vertices of the list?
Yes. If the mesh of polygons is square, this value will always be the square
root of the total number of vertices in the list. (One can arrive at these
results with integer (whole number) division, and the remainder of integer
division, when the mesh is not square, but that's another story which we
will reserve for another tutorial.)
import Blender
from Blender NMesh import
# Some mathematical functions from the
Python module
# would be very useful, but
since Python is very efficient,
# it only loads the minimum that it requires.
# Thus, we must request that the math
module be imported.
import math
from math import *
# Creation of the mesh of polygons
me=NMesh.GetRaw()
# Without tackling the problem of local
and global variables,
# it is better (I prefer) to declare and
initialize
# the variables outside of the subroutines.
i=0
j=0
# This is an example of what was
explained in the text.
# The value 9 is assigned to the variable
totalvert.
totalvert = 9
# Applying the results of our discussion
systematically,
# the square root of totalvert is
obtained with
# the function sqrt(). Notice that
if the line:
# " from math import * " had not
been used in the script above,
# it would have been necessary to
write " math.sqrt(totalvert) "
n = sqrt(totalvert)
for i in range(0, n, 1):
# The first subroutine
begins here
# with four spaces
of indentation
for j in range(0, n,
1):
# The second loop begins here
# with eight spaces of indentation
v=NMesh.Vert(j, i, 0.0)
me.verts.append(v)
# End of the internal loop
# End of the external
loop
# Let's take a break before continuing
# with automating face creation.
# It's always possible to test this
script
# in its present state, but you must add:
# NMesh.PutRaw(me, "plane", 1)
# and
# Blender.Redraw() 
