[Verse-dev] pyverse r1p1

Brecht Van Lommel verse-dev@blender.org
03 May 2004 22:53:27 +0000


--=-Qc27fK5mMg1fUnh20+vL
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hi all,

I've updated pyverse to work with the current verse release (r1p1).
Support for the Audio functions is still missing. Next to updating, I
have also changed how pyverse deals with it's namespace. Instead of
using prefixes like verse_, VN_, V_, ..., it now simply leaves those
out. So now the python code should look like, for example:

import verse as v
v.send_node_create(...)
if type == v.GEOMETRY:
vmf = v.MFColor()
...

I've included the updated tutorial.py, and a very primitive wavefront
.obj loader example script. The .obj loader hasn't really been tested,
as I couldn't get connector / loq airou compiled that easily with the
new verse release, but I thought I'd include it anyway.

It's available here:
http://projects.blender.org/projects/pyverse/

One thing that seemed odd to me in the verse api is this:
extern void verse_send_connect_deny(void *address);
Why is address a void*?

Also, verse_send_connect_deny and verse_send_connect_accept pass address
as an uninitialized variable to the callback function.

Cheers,
Brecht

--=-Qc27fK5mMg1fUnh20+vL
Content-Disposition: attachment; filename=tutorial.py
Content-Type: application/x-python; name=tutorial.py
Content-Transfer-Encoding: base64

IyEgL3Vzci9iaW4vZW52IHB5dGhvbg0KDQojIFRoaXMgdHV0b3JpYWwgY29ubmVjdHMgdXMgdG8g
YSB2ZXJzZSBzZXJ2ZXIgYW5kIGFza3MgdGhlIHNlcnZlciBmb3IgYW55DQojIG5vZGVzLCBpdCBj
YW4gYWxzbyBjcmVhdGUgYSBub2RlIGlmIHlvdSBzZXQgdGhlIG90aGVyIGFjY2VwdCBjb25uZWN0
DQojIGNhbGxiYWNrLiBGaXJzdCB3ZSBkZWZpbmUgYSBjYWxsIGJhY2sgZm9yIHRoZSBuZXR3b3Jr
IHRvIHVwZGF0ZSBpZiBvdXINCiMgY29ubmVjdGlvbiBnZXRzIGFjY2VwdGVkLg0KDQppbXBvcnQg
dmVyc2UgYXMgdg0KDQojLS0tLS0gdGhlc2UgdHdvIGNhbGxiYWNrcyBjYW4gYmUgdXNlZCBpZiB5
b3Ugd2FudCB0byBjcmVhdGUgc29tZSBkYXRhIC0tLS0tLQ0KbXlfYXZhdGFyID0gLTENCg0KIyB0
aGlzIG9uZSBpcyBmb3IgY3JlYXRpbmcgYSBub2RlDQpkZWYgY2Jfc2VuZF9jb25uZWN0X2FjY2Vw
dChhdmF0YXIsIGFkZHJlc3MpOg0KCWdsb2JhbCBteV9hdmF0YXINCglteV9hdmF0YXIgPSBhdmF0
YXINCg0KCXByaW50ICJjYl9zZW5kX2Nvbm5lY3RfYWNjZXB0OiB3ZSBqdXN0IGdvIGNvbm5lY3Rl
ZCB0byBhIHZlcnNlIHNlcnZlciEiDQoNCgl2LnNlbmRfbm9kZV9jcmVhdGUoLTEsIHYuT0JKRUNU
LCBhdmF0YXIpOw0KCXYuc2VuZF9ub2RlX2NyZWF0ZSgtMiwgdi5HRU9NRVRSWSwgYXZhdGFyKTsN
Cgl2LnNlbmRfbm9kZV9jcmVhdGUoLTMsIHYuTUFURVJJQUwsIGF2YXRhcik7DQoJdi5zZW5kX25v
ZGVfY3JlYXRlKC00LCB2LkJJVE1BUCwgYXZhdGFyKTsNCg0KCW1hc2sgPSAwDQoJZm9yIGkgaW4g
cmFuZ2UoMCwgdi5OVU1fVFlQRVMpOg0KCQltYXNrID0gbWFzayB8ICgxIDw8IGkpDQoJdi5zZW5k
X25vZGVfbGlzdChtYXNrKQ0KDQojIHNlY29uZCB3ZSBkZWZpbmUgYSBjYWxsIGJhY2sgZm9yIHRo
ZSBuZXR3b3JrIHRvIHVwZGF0ZSBpZiBpdCB3YW50cyB0byBpbmZvcm1zIA0KIyB1cyBvZiBhbnkg
bm9kZXMNCmRlZiBjYl9zZW5kX25vZGVfY3JlYXRlX2NyZWF0ZShub2RlX2lkLCB0eXBlLCBvd25l
cl9pZCk6DQoJZ2xvYmFsIG15X2F2YXRhcg0KDQoJIyBwcmludGluZyB0aGUgbm9kZSBpZA0KCXBy
aW50ICJXZSBmb3VuZCBhIG5vZGUhIGl0IGlzIG9mIGlkID0gIiArIHN0cihub2RlX2lkKQ0KDQoJ
IyBkaWQgd2UgcmVhbHkgY3JlYXRlIHRoaXMgbm9kZSBvciBkaWQgc29tZSBvbmUgZWxzZT8NCglp
ZiBvd25lcl9pZCA9PSBteV9hdmF0YXI6DQoJCWlmIHR5cGUgPT0gdi5PQkpFQ1Q6DQoJCQlwcmlu
dCAiaXRzIGEgb2JqZWN0IG5vZGUhIg0KCQkJIyBsZXRzIHNldCB0aGUgbm9kZSB0byBlbWl0IGxp
Z2h0IQ0KCQkJdi5zZW5kX29fbGlnaHRfc2V0KG5vZGVfaWQsIDEsIDEsIDEpDQoJCQkjIHJpZ2h0
IG5vdyB3ZSBoYXZlIG5vdCBzdG9yZWQgYW55IGlkcyBvZiBhbnkgbm9kZXMgdG8gcG9pbnQgdG8N
CgkJCSMgaWYgd2UgZGlkIHdlIGNvdWxkIHVzZSB2LnNlbmRfb19saW5rX3NldCB0byBzZXQgc29t
ZSBsaW5rcw0KCQkJIyB0byBvdGhlciBub2Rlcw0KDQoJCWVsaWYgdHlwZSA9PSB2LkdFT01FVFJZ
Og0KCQkJcHJpbnQgIml0cyBhIGdlb21ldHJ5IG5vZGUhIg0KCQkJIyBsZXRzIGNyZWF0ZSBzb21l
IGxheWVycyEgaG93IGFib3V0IHR3byBsYXllcnMgdG8gc3RvcmUgdXYgZGF0YSBpbj8NCgkJCXYu
c2VuZF9nX2xheWVyX2NyZWF0ZShub2RlX2lkLCAxLCAidGV4X3UiLCB2LkdfTEFZRVJfUE9MWUdP
Tl9DT1JORVJfUkVBTDY0LCAwLCAwKQ0KCQkJdi5zZW5kX2dfbGF5ZXJfY3JlYXRlKG5vZGVfaWQs
IDIsICJ0ZXhfdiIsIHYuR19MQVlFUl9QT0xZR09OX0NPUk5FUl9SRUFMNjQsIDAsIDApDQoJCQkj
IGxldHMgZ2V0IHdpbGQgYW5kIGNyZWF0ZSAzIGxheWVycyB0byBzdG9yZSBhIGNvbG9yIGZvciBl
YWNoIHZlcnRleCB0b28NCgkJCXYuc2VuZF9nX2xheWVyX2NyZWF0ZShub2RlX2lkLCAzLCAiY29s
X3IiLCB2LkdfTEFZRVJfVkVSVEVYX1JFQUw2NCwgMCwgMCkNCgkJCXYuc2VuZF9nX2xheWVyX2Ny
ZWF0ZShub2RlX2lkLCA0LCAiY29sX2ciLCB2LkdfTEFZRVJfVkVSVEVYX1JFQUw2NCwgMCwgMCkN
CgkJCXYuc2VuZF9nX2xheWVyX2NyZWF0ZShub2RlX2lkLCA1LCAiY29sX2IiLCB2LkdfTEFZRVJf
VkVSVEVYX1JFQUw2NCwgMCwgMCkNCgkJCSMgbGV0cyBjcmVhdGUgYSBmZXcgdmVydGljZXMNCgkJ
CSMgbGF5ZXIgb25lIGlzIGFsd2F5cyB0aGUgYmFzZSB2ZXJ0ZXggbGF5ZXINCgkJCXYuc2VuZF9n
X3ZlcnRleF9zZXRfcmVhbDY0X3h5eihub2RlX2lkLCAwLCAwLCAxLCAwLCAwKQ0KCQkJdi5zZW5k
X2dfdmVydGV4X3NldF9yZWFsNjRfeHl6KG5vZGVfaWQsIDEsIDAsIDAsIDEsIDApDQoJCQl2LnNl
bmRfZ192ZXJ0ZXhfc2V0X3JlYWw2NF94eXoobm9kZV9pZCwgMiwgMCwgMCwgMCwgMSkNCgkJCSMg
YW5kIHdoeSBub3QgY3JlYXRlIGEgcG9seWdvbiENCgkJCSMgbGF5ZXIgdHdvIGlzIGFsd2F5cyB0
aGUgYmFzZSBwb2x5Z29uIGxheWVyLCB0aGUgZm91cnRoIGNvcm5lciBpcw0KCQkJIyBzZXQgdG8g
LTEgdG8gY3JlYXRlIGEgdHJpYW5nbGUNCgkJCXYuc2VuZF9nX3BvbHlnb25fc2V0X2Nvcm5lcl91
aW50MzIobm9kZV9pZCwgMCwgMSwgMCwgMSwgMiwgLTEpDQoNCgkJZWxpZiB0eXBlID09IHYuTUFU
RVJJQUw6DQoJCQlwcmludCAiaXRzIGEgbWF0ZXJpYWwgbm9kZSEiDQoJCQkjIGxldHMgY3JlYXRl
IGEgZmV3IGZyYWdtZW50cw0KCQkJZnJhZ21lbnQgPSB2Lk1GT3V0cHV0KCkNCgkJCSMgdGhlIGZy
b250IG9mIHRoaXMgbWF0ZXJpYWwgc2hvdWxkIHN0YXJ0IGhlcmUNCgkJCWZyYWdtZW50LmZyb250
ID0gNDsNCgkJCSMgdGhlIGJhY2sgb2YgdGhpcyBtYXRlcmlhbCBzaG91bGQgYmxhY2sNCgkJCWZy
YWdtZW50LmJhY2sgPSAwDQoJCQlmcmFnbWVudC50eXBlID0gImNvbG9yIg0KCQkJdi5zZW5kX21f
ZnJhZ21lbnRfY3JlYXRlKG5vZGVfaWQsIDEsIHYuTV9GVF9PVVRQVVQsIGZyYWdtZW50KQ0KDQoJ
CQlmcmFnbWVudCA9IHYuTUZDb2xvcigpDQoJCQlmcmFnbWVudC5yZWQgPSAxDQoJCQlmcmFnbWVu
dC5ncmVlbiA9IDAuMQ0KCQkJZnJhZ21lbnQuYmx1ZSA9IDAuMQ0KCQkJdi5zZW5kX21fZnJhZ21l
bnRfY3JlYXRlKG5vZGVfaWQsIDIsIHYuTV9GVF9DT0xPUiwgZnJhZ21lbnQpDQoNCgkJCSMgaSB3
YW50IG15IG1hdGVyaWFsIHRvIGJlIGluZmx1ZW5jZWQgYnkgdGhlIGluY29tbWluZyBsaWdodCBz
byBsZXRzDQoJCQkjIGNyZWF0ZSBhIGxpZ2h0IGZyYWdtZW50DQoJCQlmcmFnbWVudCA9IHYuTUZM
aWdodCgpDQoJCQkjIHdlIGFyZSBub3QgZ29pbmcgdG8gdXNlIGFueSBvZiB0aGF0IC4uLg0KCQkJ
ZnJhZ21lbnQuYnJkZiA9IDANCgkJCWZyYWdtZW50LmJyZGZfciA9ICIiDQoJCQlmcmFnbWVudC5i
cmRmX2cgPSAiIg0KCQkJZnJhZ21lbnQuYnJkZl9iID0gIiINCgkJCSMgdGhlIHN1cmZhY2UgaXMg
cGVyZmVjdGx5IHNtb290aA0KCQkJZnJhZ21lbnQubm9ybWFsX2ZhbGxvZmYgPSAwDQoJCQkjIHRo
aXMgbWF0ZXJpYWwgaXMgbGl0IGJ5IGJvdGggZGlyZWN0IGFuZCBhbWJpZW50IGxpZ2h0DQoJCQlm
cmFnbWVudC50eXBlID0gdi5NX0xJR0hUX0RJUkVDVF9BTkRfQU1CSUVOVA0KCQkJdi5zZW5kX21f
ZnJhZ21lbnRfY3JlYXRlKG5vZGVfaWQsIDMsIHYuTV9GVF9MSUdIVCwgZnJhZ21lbnQpDQoJCQkJ
CQ0KCQkJIyBvayBsZXRzIG5vdyBtaXggdGhlIHJlZCBjb2xvciB3aGl0IHRoZSBpbmNvbW1pbmcg
bGlnaHQhDQoJCQlmcmFnbWVudCA9IHYuTUZCbGVuZGVyKCkNCgkJCSMgdGhlIHJlZCBjb2xvcg0K
CQkJZnJhZ21lbnQuZGF0YV9hID0gMg0KCQkJIyB0aGUgbGlnaHQNCgkJCWZyYWdtZW50LmRhdGFf
YiA9IDMNCgkJCSMgdGhpcyBibGVuZCBtb2RlIGRvZXMgbm90IHVzZSBjb250cm9sDQoJCQlmcmFn
bWVudC5jb250cm9sID0gMA0KCQkJIyB3ZSB3YW50IHRoZSB0d28gdG8gYmUgbXVsdGlwbHllZCB0
b2dldGhlcg0KCQkJZnJhZ21lbnQudHlwZSA9IHYuTV9CTEVORF9NVUxUSVBMWQ0KCQkJdi5zZW5k
X21fZnJhZ21lbnRfY3JlYXRlKG5vZGVfaWQsIDQsIHYuTV9GVF9CTEVOREVSLCBmcmFnbWVudCkN
Cg0KCQkJIyB0aGUgbWF0ZXJpYWwgZXhhbXBsZSBhYm92ZSBpcyBub3QgZm9vbCBwcm9mLCB0byBi
ZSBjcnJlY3QgeW91DQoJCQkjIHNob3VsZCBub3QgYXMgaSBoYXZlIGRvbmUgaGVyZSBhc3N1bWUg
dGhhdCB0aGUgZnJhZ21lbnRzIHdpbGwgZ2V0DQoJCQkjIHRoZSBudW1iZXJzIHRoYXQgaSBoYXZl
IGFzc2lnbmVkIHRvIHRoZW0sIEl0IG1heSB3b3JrIGluIHRoaXMNCgkJCSMgaW1wbGVtZW50YXRp
b24gYnV0IGlzIHdlcnkgZ29vZC4gd2hhdCB5b3Ugc2h1bGQgZG8gaXMgc2VuZCB0aGUgDQoJCQkj
IGZyYWdtZW50cyBvdXQgYW5kIHRoZW4gd2FpdCBmb3IgdGhlbSB0byBjb21lIGJhY2sgdG8gc2Vl
IHdoYXQgaXMNCgkJCSMgdGhleSBnb3QsIGFuZCBhZnRlciB0aGF0IHlvdSBjYW4gY3JlYXRlIHRo
ZSBmcmFnbWVudHMgdGhhdCBwb2ludHMNCgkJCSMgdG8gdGhlbS4gVGhpcyByZXF1aWVzIHF1aXRl
IGEgbG90IG1vcmUgcm91bmQgdHJpcCBhbmQgd291bGQgYmUNCgkJCSMgdG9vIGhhcmQgdG8gZm9s
b3cgZm9yIGEgc2ltcGxlIHR1dG9yaWFsIGFzIHRoaXMgb25lLg0KDQoJCWVsaWYgdHlwZSA9PSB2
LkJJVE1BUDoNCgkJCXByaW50ICJpdHMgYSBiaXRtYXAgbm9kZSEiDQoNCgkJCSMgY29vbCB3ZSBo
YXZlIGEgYml0bWFwIGxldHMgZmlyc3Qgc2V0IHRoZSBzaXplIG9mIGl0LCBhIDJEIDI1NioyNTYN
CgkJCSMgd2lsbCBiZSBmaW5lDQoJCQl2LnNlbmRfYl9pbml0X2RpbWVuc2lvbnMobm9kZV9pZCwg
MjU2LCAyNTYsIDEpDQoJCQkjIGkgd2lsbCBuZWVkIDMgY2hhbmVscyAocmdiKSBhbmQganVzdCB0
byBiZSBjb29sIGxldHMgaGF2ZSB0aGVtDQoJCQkjIGJlIDMyIGJpdCBmbG9hdHMNCgkJCXYuc2Vu
ZF9iX2xheWVyX2NyZWF0ZShub2RlX2lkLCAxLCAiY29sX3IiLCB2LkJfTEFZRVJfUkVBTDMyKQ0K
CQkJdi5zZW5kX2JfbGF5ZXJfY3JlYXRlKG5vZGVfaWQsIDIsICJjb2xfZyIsIHYuQl9MQVlFUl9S
RUFMMzIpDQoJCQl2LnNlbmRfYl9sYXllcl9jcmVhdGUobm9kZV9pZCwgMywgImNvbF9iIiwgdi5C
X0xBWUVSX1JFQUwzMikNCg0KCQkJIyB0aGlzIGlzIHRoZSB0aWxlIHdlIGFyZSBnb2luZyB0byBz
ZW5kICh0aWxlcyBhcmUgYWxsd2F5cyAyRCkNCgkJCWRhdGEgPSBbXQ0KCQkJZm9yIGkgaW4gcmFu
Z2UoMCwgIHYuQl9USUxFX1NJWkUgKiB2LkJfVElMRV9TSVpFKToNCgkJCQkjIGxldHMgY3JlYXRl
IHNvbWUgc3RyaXBlcyAoVGhlIGFpciBuZWFyIG15IGZpbmdlcnMpDQoJCQkJZGF0YS5hcHBlbmQo
ZmxvYXQoaSAlIDIpKQ0KDQoJCQl2LnNlbmRfYl9sYXllcl9zZXRfdGlsZShub2RlX2lkLCAwLCAw
LCAwLCAwLCB2LkJfTEFZRVJfUkVBTDMyLCBkYXRhKQ0KCQkJIyBhZ2FpbiB3ZSBhc3VtZWQgdGhh
dCBvbmUgb2YgdGhlIHRocmVlIGxheWVycyB3b3VsZCBnZXQgaWQgMCwNCgkJCSMgcHJlc3VtYWJs
eSByZWQsIGJ1dCB0aGVyZSBpcyBubyB3YXkgb2Yga25vd2luZyBzbyBpZiB5b3Ugd3JpdGUgYQ0K
CQkJIyByZWFsIGFwcCB3YWl0IGZvciB0aGUgdi5zZW5kX2JfbGF5ZXJfY3JlYXRlIGNhbGxzIHRv
IGJlDQoJCQkjIGNvbmZpcm1lZCBmcm9tIHRoZSBob3N0DQoNCiMgLS0tLS0gdGhlc2UgdHdvIGNh
bGxiYWNrcyBhcmUgdG8gYmUgdXNlZCBvZiB5b3Ugd2FudCB0byBqdXN0IGxpc3RlbiAtLS0tLS0t
DQoNCmRlZiBjYl9zZW5kX2Nvbm5lY3RfYWNjZXB0X2xpc3RlbihhdmF0YXIsIGFkZHJlc3MpOg0K
CXByaW50ICJjYl9zZW5kX2Nvbm5lY3RfYWNjZXB0OiB3ZSBqdXN0IGdvIGNvbm5lY3RlZCB0byBh
IHZlcnNlIHNlcnZlciFcbiINCglwcmludCAibGlzdGluZyBub2RlczoiDQoJbWFzayA9IDANCglm
b3IgaSBpbiByYW5nZSgwLCB2Lk5VTV9UWVBFUyk6DQoJCW1hc2sgPSBtYXNrIHwgKDEgPDwgaSkN
Cgl2LnNlbmRfbm9kZV9saXN0KG1hc2spDQoNCmRlZiBjYl9zZW5kX25vZGVfY3JlYXRlX2xpc3Rl
bihub2RlX2lkLCB0eXBlLCBvd25lcl9pZCk6DQoJcHJpbnQgIldlIGZvdW5kIGEgbm9kZSEgaXQg
aXMgb2YgaWQgPSAiICArIHN0cihub2RlX2lkKQ0KCWlmIHR5cGUgPT0gdi5PQkpFQ1Q6DQoJCXBy
aW50ICJpdHMgYSBvYmplY3Qgbm9kZSEiDQoJZWxpZiB0eXBlID09IHYuR0VPTUVUUlk6DQoJCXBy
aW50ICJpdHMgYSBnZW9tZXRyeSBub2RlISINCgllbGlmIHR5cGUgPT0gdi5NQVRFUklBTDoNCgkJ
cHJpbnQgIml0cyBhIG1hdGVyaWFsIG5vZGUhIg0KCWVsaWYgdHlwZSA9PSB2LkJJVE1BUDoNCgkJ
cHJpbnQgIml0cyBhIGJpdG1hcCBub2RlISINCgllbGlmIHR5cGUgPT0gdi5URVhUOg0KCQlwcmlu
dCAiaXRzIGEgdGV4dCBub2RlISINCgllbGlmIHR5cGUgPT0gdi5QQVJUSUNMRToNCgkJcHJpbnQg
Iml0cyBhIHBhcnRpY2xlIG5vZGUhIg0KCWVsaWYgdHlwZSA9PSB2LkNVUlZFOg0KCQlwcmludCAi
aXRzIGEgY3VydmUgbm9kZSEiDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0aGUg
bWFpbiBmdW5jdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KZGVmIG1haW4oKToN
CglzZXJ2ZXJfYWRkcmVzcyA9ICJsb2NhbGhvc3QiDQoNCgkjIGZpcnN0IHdlIHNldCB0aGUgY2Fs
bGJhY2tzDQoJdi5jYWxsYmFja19zZXQodi5TRU5EX0NPTk5FQ1RfQUNDRVBULCBjYl9zZW5kX2Nv
bm5lY3RfYWNjZXB0KQ0KCXYuY2FsbGJhY2tfc2V0KHYuU0VORF9OT0RFX0NSRUFURSwgY2Jfc2Vu
ZF9ub2RlX2NyZWF0ZV9jcmVhdGUpDQoNCgkjIHNldCB0aGVzZSBjYWxsYmFja3MgaWYgeW91IGp1
c3Qgd2FudCB0byBsaXN0ZW4NCgkjIHYuY2FsbGJhY2tfc2V0KFNFTkRfQ09OTkVDVF9BQ0NFUFQs
IGNiX3NlbmRfY29ubmVjdF9hY2NlcHRfbGlzdGVuKQ0KCSMgdmxsX2NhbGxiYWNrX3NldChTRU5E
X05PREVfQ1JFQVRFLCBjYl9zZW5kX25vZGVfY3JlYXRlX2xpc3RlbikNCg0KCXByaW50ICJhbGwg
Y2FsbGJhY2tzIHNldCINCgkNCgkjIG5vdyB3ZSBjb25uZWN0IHRvIHRoZSBzZXJ2ZXINCgljb25u
ZWN0aW9ucyA9IHYuc2VuZF9jb25uZWN0KCJNeV9uYW1lIiwgIk15X3Bhc3N3b3JkIiwgc2VydmVy
X2FkZHJlc3MpDQoJcHJpbnQgImF0dGVtcHRlZCB0byBjb25uZWN0IHRvIHNlcnZlciAiICsgc2Vy
dmVyX2FkZHJlc3MNCg0KCSMgd2Ugc2V0IHRoZSBzZXNzaW9uIHdlIHdhbnQgdG8gdXBkYXRlICh2
ZXJzZSBjYW4gaGFuZGxlIG1vcmUgdGhlbiBvbmUhKQ0KCXYuc2Vzc2lvbl9zZXQoY29ubmVjdGlv
bnMpIA0KCXByaW50ICJzZXNzaW9uIHNldCINCg0KCSMgKGFsbW9zdCkgaW5maW5pdCBsb29wDQoJ
aSA9IDANCgl3aGlsZSBpIDwgMTAwMDogDQoJCSMgbGlzdGVuIHRvIHRoZSBuZXR3b3JrICh3YWl0
IG5vIG1vcmUgdGhlbiAxMDAgbXMpIGFuZCB1cGRhdGUgdGhlIGNhbGxiYWNrcw0KCQl2LmNhbGxi
YWNrX3VwZGF0ZSgxMDApOyANCgkJI2lmIHYuc2Vzc2lvbl9nZXRfc2l6ZSgpID4gNTAwMDoNCgkJ
Iwl2LnNlbmRfY29ubmVjdF90ZXJtaW5hdGUoIkltIHF1aXRpbmcgYmVjb3VzZSB5b3UgZG9udCBy
ZXR1cm4gbXkgY2FsbHMhICh3aGF0IGV2ZXIgaGFwcGVuZCB0byB1cz8pIikNCgkJIwlwcmludCAi
SW0gcXVpdGluZyBiZWNvdXNlIHlvdSBkb250IHJldHVybiBteSBjYWxscyEgKHdoYXQgZXZlciBo
YXBwZW5kIHRvIHVzPykiDQoJCSMJdi5zZXNzaW9uX2Rlc3Ryb3koY29ubmVjdGlvbnMpDQoJCSMJ
YnJlYWsNCgkJaSArPSAxDQoNCm1haW4oKQ0KDQo=

--=-Qc27fK5mMg1fUnh20+vL
Content-Disposition: attachment; filename=obj.py
Content-Type: application/x-python; name=obj.py
Content-Transfer-Encoding: 7bit


import string
import verse as v

avatar = -1
vlist = []
uvlist = []
flist = []

# small utility function
def isspace(character):
	return character in string.whitespace

# wavefront .obj file reader
def read_obj_file(filename):
	f = file(filename, "r")

	vlist = []
	uvlist = []
	flist = []

	lines = f.readlines()
	for line in lines:
		# ignore comment or empty line
		if line[0] == "#" or line[0] == "\n":
			pass

		# add vertex
		elif line[0] == "v" and isspace(line[1]):
			co = line.split()
			vlist.append((float(co[1]), float(co[2]), float(co[3])))

		# add uv coord
		elif line[0:2] == "vt" and isspace(line[2]):
			uvco = line.split()
			uvlist.append((float(uvco[1]), float(uvco[2])))
		
		# add face
		elif line[0] == "f" and isspace(line[1]):
			fdata = line.split()
			del fdata[0]

			if len(fdata) >= 3:
				f = []
				for vert in fdata:
					ids = vert.split("/")
					# .obj id's start at 1
					v_id = int(ids[0]) - 1
					if len(ids) >= 2: uv_id = int(ids[1]) - 1
					else: uv_id = -1
					f.append((v_id, uv_id))
	
				flist.append(f)
	
	return vlist, uvlist, flist

# send verts to server
def send_verts(node_id, layer_id):
	global vlist
	id = 0
	for vert in vlist:	
		x, y, z = vert[0], vert[1], vert[2]
		v.send_g_vertex_set_real32_xyz(node_id, layer_id, id, x, y, z)
		if id % 20 == 0:
			v.callback_update(0)
		id = id + 1

# send faces to server (ngons are simply ignored)
def send_faces(node_id, layer_id):
	global flist
	id = 0
	for f in flist:
		v1 = f[0][0]
		v2 = f[1][0]
		v3 = f[2][0]
		if len(f) > 3: v4 = f[3][0]
		else: v4 = -1
		v.send_g_polygon_set_corner_uint32(node_id, layer_id, id, v1, v2, v3, v4)
		if id % 20 == 0:
			v.callback_update(0)
		id = id + 1

# send uv's to server (index = 0 -> u, index = 1 -> v)
def send_uv(node_id, layer_id, index):
	global flist
	id = 0
	for f in flist:
		id = f[0][1]
		if id < len(uvlist): v1 = uvlist[id][index]
		else: v1 = 0
		id = f[1][1]
		if id < len(uvlist): v2 = uvlist[id][index]
		else: v2 = 0
		id = f[2][1]
		if id < len(uvlist): v3 = uvlist[id][index]
		else: v3 = 0
		if len(f) > 3:
			id = f[3][1]
			if id < len(uvlist): v4 = uvlist[id][index]
			else: v4 = 0
		else:
			v4 = 0

		v.send_g_polygon_set_corner_real64(node_id, layer_id, id, v1, v2, v3, v4)
		if id % 20 == 0:
			v.callback_update(0)
		id = id + 1

def cb_connect_accept(v_avatar, address):
	global avatar
	avatar = v_avatar
	v.send_node_create(-1, v.GEOMETRY, avatar)
	v.send_node_list(1 << v.GEOMETRY)

def cb_node_create(node_id, type, owner_id):
	global avatar
	if owner_id == avatar and type == v.GEOMETRY:
		v.send_g_layer_create(node_id, 2, "tex_u", v.G_LAYER_POLYGON_CORNER_REAL64, 0, 0)
		v.send_g_layer_create(node_id, 3, "tex_v", v.G_LAYER_POLYGON_CORNER_REAL64, 0, 0)
		v.send_node_subscribe(node_id)

def cb_g_layer_create(node_id, layer_id, name, type, def_uint, def_real):
	if layer_id == v.G_LAYER_VERTEX_XYZ:
		send_verts(node_id, layer_id)
	elif layer_id == v.G_LAYER_POLYGON_CORNER_UINT32:
		send_faces(node_id, layer_id)
	elif type == v.G_LAYER_POLYGON_CORNER_REAL64:
		if name == "tex_u":
			send_uv(node_id, layer_id, 0)
		elif name == "tex_v":
			send_uv(node_id, layer_id, 1)

def main():
	global avatar, vlist, uvlist, flist

	vlist, uvlist, flist = read_obj_file("test.obj")

	v.callback_set(v.SEND_CONNECT_ACCEPT, cb_connect_accept)
	v.callback_set(v.SEND_NODE_CREATE, cb_node_create)
	v.callback_set(v.SEND_G_LAYER_CREATE, cb_g_layer_create)

	# connect and make active session
	session = v.send_connect("uname", "pass", "192.168.123.159")
	v.session_set(session)

	i = 0
	while i < 10000:
		v.callback_update(0)
		i = i + 1

main()

--=-Qc27fK5mMg1fUnh20+vL--