by tachzusamm » Thu Apr 07, 2011 9:46 pm
Okay guys.
First, to avoid confusion: There is NO fixed limit to "10000 faces". Neither in Blender, nor in PyPRP, nor in Plasma.
And, there is NO fixed limit to "8000 vertices" as well. In fact, there IS a limit: This is currently set by PyPRP to 32768 vertices (which is written 0x8000 in hexadecimal), and this limits the total number of vertices which can be stored in a "buffer group". But this "buffer group" is not the mesh you created.
What happens in PyPRP: A textured mesh you created in Blender gets - well, lets say: transformed into a list of vertices. Those vertices are not simply the real vertices of the mesh, but are calculated based on how the UV map looks like. Imagine this as some sort of projection, although it's a bit more complex operation.
In fact, the number of vertices in this list of vertices (which is called a "buffer group") can grow *above* three times the number of used faces in the mesh.
This is why it appears sometimes the faces are limited. For example, for a mesh with 10000 faces, the calculated number of vertices in the buffer group can be greater than 3*faces, for example 35000 vertices - then the export will stop with an exception (because 35000 > 32768) and you get the "vertex count too high" message (which is confusing in my opinion, because it's not the vertex count of your mesh).
Now, why IS there a limit?
It's because the size of this list of transformed vertices in the buffer group has to be written into the exported files as well. In fact, the vertex list is just an indexed array, and its size has to be written using functions which are currently limited to unsigned short integer (16 bit) range (which has a maximum of 65535 = 0x0FFFF).
I don't know if this limitation is based on the Plasma files structure or if it's just a limitation of the basic read/write functions used in prp_Stream.py .
Maybe we can't get beyond this 65535 limit (if it's the Plasma structure) - or maybe we can (if it's the stream lib limitation).
The good news is that we CAN increase the limit a bit (to twice, that is). It you have read carefully, the limit is currently set to 32768 - but there's no need for "signed" short integer, we can extend it to unsigned short, which means 65535. (By the way, 32768 (0x8000) is already above the positive short integer limit which would be 32767, so checking for > 0x8000 is simply not exact. It should be >= 0x8000 or > 0x0FFF.)
I've already done this, and was able to export a mesh with more than 17000 faces, which generated a vertex count of about 56000 in the buffer group, without problems in the exported age.
[
Technical: In line 1276 of prp_DrawClasses.py I replaced the 0x8000 with 0x0FFFF. Four Fs with a leading 0.
OLD: "if len(MatGroup["vertices"]) > 0x8000:"
NEW: "if len(MatGroup["vertices"]) > 0x0FFFF:"
And I replaced the next line:
raise RuntimeError, "Vertex count on this material is too high, consider breaking up your object into several materials...."
with this:
raise RuntimeError, "Vertex count (=%i) on this material is above 65535, consider breaking up your object into several materials...." %len(MatGroup["vertices"])
to get an idea of the real calculated vertex count in the buffer group in case of an export error.
]
But don't try to increase the limit above this value - this will surely crash your age with a stack error.
Cheers,
tach
P.S.: I assume the 0x8000 in line 1197:
and bufferGroup.GetUVCount()==UVCount and len(bufferGroup.fVertBuffStorage)+num_vertexs<0x8000:
could/should be adapted as well like this:
and bufferGroup.GetUVCount()==UVCount and len(bufferGroup.fVertBuffStorage)+num_vertexs<0x0FFFF:
but not sure here. I think there's just a new group generated when an already available one is too filled - which should not harm.
Again, not sure here about what will happen under special circumstances.