<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
  <title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Hi All, this doc is ment to help people who are relativly new to
python, to optimize python importers and exporters with some extra
hints.<br>
Feel free make any suggestions/corrections.<br>
- Cam<br>
<p style="margin-top: 0.17in; page-break-after: avoid;" align="center"><font
 face="Arial, sans-serif"><font size="5"><b>Writing
Optimal Exporters and Importers for Blender:Python</b></font></font></p>
<p><br>
<br>
</p>
<ol>
  <li>
    <p><font face="Verdana"><b>Getting Mesh data </b><span style=""><i>(Exporting
Only)</i></span><br>
A recently added function removes the need for doing an<br>
    <samp>ob.getData().name</samp><br>
simply to get the name of the object.<br>
Instead use* <samp>obj.getData(1)</samp> ... meaning *<samp>o<samp>bj.</samp>getData(1=name_only)</samp>,
    <br>
this is nice because it works for all data types, its just that <br>
Mesh's are not just thin wrappers like most of the other Types in <br>
blender so you want to avoid <samp>mesh.getData()</samp> as much as
possible, its best practice only <br>
calling each mesh data once. <br>
    </font><br>
    <br>
    </p>
  </li>
  <li>
    <p><font face="Verdana"><b>Use new python functionality
mesh.transform() <i> </i></b><i><span style="">(Exporting Only)</span></i><br>
Of course this wasn't in python until 2 days ago :) but its very <br>
useful and on my PC is over 100 times faster then transforming each <br>
vert's location and normal by a matrix within python. <br>
make sure that if you are only exporting locations you add a 1,* <samp>mesh.transfrom(matrix,
1=location_only)</samp>* This avoids un-needed vertex normal
transforming. <br>
    </font><br>
    <br>
    </p>
  </li>
  <li>
    <p><font face="Verdana"><b>Be ware of python hogging memory.</b> <span
 style=""><i>(python generally)</i></span><br>
You may ignore this point though It has forced my into having 4 gig of
ram, so I take it seriously :) . <br>
    </font><br>
    <br>
    </p>
    <p><font face="Verdana">A List in python (and therefor blender) is
never? deallocated, <br>
python can re-use the memory whilst the script is running. <br>
    <br>
Basically making large lists in python and a lot of recursive variable <br>
assignment can leak memory that can only be regained with a restart. <br>
- *If you can- avoid making large lists. <br>
    <br>
This is Fixed in Python 2.4rc1, and will compile with blender.<br>
    <span style=""><br>
    </span></font><br>
    <br>
    </p>
  </li>
  <li>
    <p><font face="Verdana"><b>Lists<br>
4.1 Removing List Items</b><span style=""><i> (Python General)</i></span></font></p>
    <p style=""><font face="Verdana">If you have a list that you want
to add onto another list, rather then appending in a for loop, try <samp>myList.extend([li1,
li2...])</samp>.</font></p>
    <p><font face="Verdana"><span style=""><br>
Use </span><samp><span style="">ls.pop(i)</span></samp><span style="">
rather then </span><samp><span style="">ls.remove(listItem)</span></samp></font></p>
    <p><font face="Verdana"><span style="">This requires you to have
the index of the list Item but is faster since remove needs to search
the list.</span><br>
    <font face="Verdana">Using pop for removing list items favors a
while loops instead of a for loop. </font><br>
    </font><br>
    <br>
    </p>
  </li>
</ol>
<p style="margin-left: 0.49in;"><font face="Verdana"><b>4.2 Don't Copy
Lists</b><span style=""><i> (Python General)</i></span></font></p>
<p style="margin-left: 0.98in; page-break-before: always;"><span
 style=""><font face="Verdana">When
passing a list/dictionary to a function, it is better to have the
function modify the list rather then returning a new list.<br>
This
means python dosn't need to create a new list in memory.<br>
</font><samp><font face="Courier New"><br>
Functions
that modify a list in there place are more efficient then functions
that create new lists. </font></samp></span>
</p>
<p style="margin-left: 0.98in;"><samp>normalize(vec) # faster: no
re-assignment<br>
<font face="Verdana">...is usually faster then.</font><br>
vec
= <samp>normalize(vec) # slower, only use for functions that are used
to make new, unlinked lists.</samp></samp></p>
<p style="margin-left: 0.98in;"><br>
<br>
</p>
<ol start="5">
  <li>
    <p><font face="Verdana"><b>Pathnames </b><span style=""><i>(Blender/Python)</i></span><br>
Blender pathnames not compatible with python's open os.isfile etc<br>
python native functions don't understand blenders // as being the
current file dir in blender. <br>
    </font><br>
    <br>
    </p>
  </li>
  <li>
    <p><font face="Verdana"><b>Correct string parsing </b><span
 style=""><i>(Import/Exporting)<br>
    </i><span style="font-style: normal;">Since many file formats are
ASCII, the way you parse/export strings can make a large difference in
how fast your program runs.<br>
When importing strings to make into blender there are a few ways to
parse the string.</span></span></font></p>
    <p style=""><b><span style="font-style: normal;"><font
 face="Verdana">6.1 Passing String</font></span></b></p>
  </li>
</ol>
<p style="margin-left: 0.98in; font-style: normal;">
<font face="Verdana">Use <samp>float(string)</samp> rather then
<samp>eval(string)</samp> and if you know the value will be an int
then int(string)<br>
float() will work for an int too but its faster
if ints are converted as ints.<br>
</font><br>
<br>
</p>
<p style="margin-left: 0.49in;"><b><span style="font-style: normal;"><font
 face="Verdana">6.2
Checking String Start/End</font></span></b></p>
<p style="margin-left: 0.98in;"><font face="Verdana">If your checking
the start of a string for a keyword, use...</font></p>
<p style="margin-left: 0.98in;"><font face="Verdana"><samp>if
line.startswith('vert '):</samp><br>
...rather then<br>
<samp>if
line[0:5] == 'vert ':</samp><br>
<br>
using Startswith is also less
likely to raise errors because calling line[0:5]can raise errors if
the string is less then 5 characters long.<br>
String.endswith('foobar')
can be used for line ending too.<br>
Also, if your unsure weather the
text is upper or lower case use lower or upper string
function.<br>
Eg.<br>
<samp>if line.upper().startswith('VERT ')</samp><br>
<br>
</font></p>
<ol start="7">
  <li>
    <p><span style=""><span style="font-style: normal;"><font
 face="Verdana"><b>Writing Strings to a File<br>
    </b><br>
There are 3 ways of joining a strings for writing/</font></span></span></p>
    <p><font face="Verdana"><span style=""><span
 style="font-style: normal;"># Pythons string addition. Dont use if you
can help it, especialy in the main data writing loop.<br>
    </span></span><samp><span style=""><span style="font-style: normal;">file.write(str1
+ ' ' + str2 + ' ' + str3 + '\n') </span></span></samp><span style=""><span
 style="font-style: normal;"><br>
    <br>
# String formatting. Use this when your writing string data from floats
and int's<br>
    </span></span><samp><span style=""><span style="font-style: normal;">file.write('%s
%s %s\n' % (str1, str2, str3)) </span></span></samp><span style=""><span
 style="font-style: normal;"><br>
    <br>
# Pythons string joining function. To join a list of strings<br>
    </span></span><samp><span style=""><span style="font-style: normal;">file.write('
'.join([str1, str2, str3]) + '\n') </span></span></samp><span style=""><span
 style="font-style: normal;"><br>
    <br>
join is fastest on many strings, string formatting is quite fast too
(better for converting data types).</span></span></font></p>
    <p><font face="Verdana"><span style=""><span
 style="font-style: normal;">And string arithmetic is slowest.<br>
    <br>
    <br>
    </span></span><br>
    </font><br>
    <br>
    </p>
  </li>
</ol>
</body>
</html>