precision issues

| Project: | Primstar - Blender Scripts for Second Life Sculpties |
| Version: | 0.9.4-git |
| Component: | Bake Sculptie |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Domino Marama |
| Status: | fixed |
Jump to:
I have created a "standard sculpty cylinder" with 32*32 faces.
I went to edit mode and there i scaled the object up to a size of 2.55 on each axis.
I defined the grid of size 0.1 so that 256 grid points fall into each axis of the bounding box of the sculpty.
I applied a snap to grid to all vertices.
I ensured, that the object dimension is still 2.55 in each axis.
Until here i have created a sculpty, which could be exactly transformed one to one into SL.
Each mesh point is located at a valid position.
Now i bake and compare the 2 suclpties with each other as follows:
i take the new object and scale it up to <2.55,2.55,2.55> and move the whole mesh until the upper left corner is located on a grid point. Now i asume, that all other vertices are also located at mesh points. But they are not. This can not be the anticipated behaviour.
I conclude, that the sculpty importer does something unexpected with the sculpt-map.
| Attachment | Size |
|---|---|
| import-issue.blend | 560.96 KB |

Comments
#1
There was a problem with round tripping sculpties. Repeated bake / import cycles were resulting in sculpties going flat on two sides. So I had to adjust things on the import to prevent the drift. I went for an adjustment that allows the bake / import cycle to work but that doesn't line up 100% with a grid. It might be possible to use the old style and a call to set_center with the appropriate offset now. Commit c9c34e639e51c49b683288517db83fa7bc40e66f on the 1st of June 2009 has the change if you want to revert it and experiment.
#2
So the imported sculpty does not look like it will look in SL ? At least not precisely. And i can no longer use the former precision technique (aligning vertices along the grid and become sure, that what you see is what you get...)
Currently what i get after reimporting the sculptmap into blender looks quite different from what i baked ;-(
Is this currently implemented behaviour now a "feature" or a "bug" ?
Unfortunately i do not know how to revert a change. Can you give me a hint for that ?
thank you
#3
It's not precisely what you'll see in SL, but I'm not sure if it's a fixable bug. I'm planning yet another rewrite of the baker code so that the buffer maps are seam aware and store the 3D value rather than the RGB. This will allow the bounding box to be created just from the values for a particular map rather than the entire mesh, so the joined mesh stuff won't be limited to 255 steps. I'll see if it can be fixed in the baker rather than the importer then.
git diff c9c34e639 c9c34e639^is the command to show the changes of that particular commit. With so much changed since, it's probably best to manually edit sculpty.py rather than using a patch file. When referring to git commit IDs, you just need to specify enough to uniquely identify it. By adding ^ on the end it means the one before it.You can use tags too.
git diff 0.9.0 0.9.1shows what changed between those versions, just switch the order to get a reversal patch.#4
Maybe it is unrelated but i have seen an interesting effect which might be of interest for your baker:
I have created a "snap to grid" tool, which pushes all vertices into "valid positions" for sculpted prims. Now after switching from python-2.5 to python-2.6 suddenly my tool started to create weird results. The points where slightly shifted and popped to the wrong locations. And this is exactly what i also have seen on your baker. I have looked through several issues with python and it looks like there is a strong dependence with the compiler which was used to create the python binaries......
Ok, i can understand my grid-snapper much better than your baker so i looked at my script and experimented with number calculations. It turned out that i can get perfect results when i turn away from floating point calculations and use integers wherever possible. So my grid snapper now works as follows:
- scale up the mesh by a factor of 10^3 (higher scale factors do not improve the precision for my purpose)
- round the result and change it to an integer value
- calculate
- scale the mesh down by the above factor
In fact i am not scaling up the whole mesh, but for each vertex snap i do the transformation locally (scale up the vertex coordinate values, calculate, scale them back down)
I could proof that this method results in precise (and expected) grid snapping. Maybe something like that can help to make the baker/importer get more predictable ? Just a guess though.
#5
If there is a difference between different versions of Python then we need to identify why.
The baker / import issue I believe is due to floating point precision errors. In other words, it's too accurate :) By scaling up and converting to integers you are introducing an imprecision, which is basically what we need to do, I'm just not sure that's the right way to go about it. I have something more like this in mind:
So basically add half a step to each direction before converting to the RGB integers by rounding down. Using an object scale of 255.0 for ease of explanation, the 0.0 to 255.0 is converted to (0.0 to 1.0) x, y and z values to feed the above code. So tracing a few values through we see:
0.0 to 0.499999 becomes 0
0.5 to 1.499999 becomes 1
122.5 to 123.499999 becomes 123
123.5 to 124.499999 becomes 124
254.5 to 255.0 becomes 255.
In other words, a pretty much ideal way for the baker to convert the mesh dimensions to integers. We just need to remove all the earlier hacks to precision and use accurate floats to this point, which is what the new bake map code will do. Any precision errors then can be tuned out just by setting the adjust value to say 1.0 / 508 or 1.0 / 512 depending on which direction the precision errors affect things.
#6
I'm going to work on the new baker code, so I've assigned this issue to me and converted it to a bug report. It's a pretty major rewrite as it'll move the bounding box calculation to the end of the bake process rather than the beginning, so I'm going to do the coding in a seperate local branch. I'll merge it to master when it's done.
#7
I've committed the new baker code and it fixes this issue. It's pretty much a complete rewrite of the bake code, and I've only put it through basic tests. This is even more flexible than the 0.5.x baker as it combines edge rendering with a sculpt map aware fill. The baker no longer gives up if the UV map is outside the image area too, it'll just bake the parts that are inside the image.
Just change this back to active if you can still find a problem Gaia, but hopefully it's fine across every case now.
#8
Hi, I'm not sure this is relevant to this issue but I think this is due to an incorrect interpretation of how sculpties are rendered (please correct me if I'm wrong).
From the SL wiki at http://wiki.secondlife.com/wiki/Sculpted_Prim_Explanation:
"On a sculpted prim that has a size of one meter, the color values from 0-255 map to offsets from -0.5 to 0.496 meters from the center. Combined with the scale vector that all prims in Second Life possess, sculpted prims have the nearly same maximum dimensions as regular procedural prims (9.961 meter diameter). The last 39mm is lost due to the fact that the maximum color value is 255, whereas 256 would be required to generate a positive offset of exactly 0.5."
--- (end of quote)
The exporter and importer seem to consider the mapping in a way that a pixel with, say, R=255 would map to X=0.5 in the example above, whereas it should map to 0.496.
I'm using version 0.9.4 by the way so I'm not sure if this has already changed. I made the following changes and it seem to give better results (I haven't tested it thoroughly though):
sculpty.py:
line 119 from:
self.scale = self.range / 255.0 self.center = (self.min + self.max * 0.5) / 255.0 - XYZ(0.5, 0.5, 0.5)to
self.scale = self.range / 256.0 self.center = (self.min + self.max * 0.5) / 256.0 - XYZ(0.5, 0.5, 0.5)
line 1303 from:
x = p[0] - 0.5 y = p[1] - 0.5 z = p[2] - 0.5to
x = (255. / 256.) * p[0] - 0.5 y = (255. / 256.) * p[1] - 0.5 z = (255. / 256.) * p[2] - 0.5
Well, that's it. Sorry I didn't have time to make a patch. Nice work with these scripts by the way!
#9
Sorry, the code excerpt got all messed up. Let me try again:
sculpty.py:
line 119 from:
self.scale = self.range / 255.0
self.center = (self.min + self.max * 0.5) / 255.0 - XYZ(0.5, 0.5, 0.5)
to
self.scale = self.range / 256.0
self.center = (self.min + self.max * 0.5) / 256.0 - XYZ(0.5, 0.5, 0.5)
line 1303 from:
x = p[0] - 0.5
y = p[1] - 0.5
z = p[2] - 0.5
to
x = (255. / 256.) * p[0] - 0.5
y = (255. / 256.) * p[1] - 0.5
z = (255. / 256.) * p[2] - 0.5
#10
Hi Watcom.
I'd be interested to see a blend file for a model that you think this change improves. If you look in http://svn.secondlife.com/trac/linden/browser/trunk/indra/llmath/llvolum... at the sculpt_rgb_to_vector function (currently at line 2173), then you'll see that dividing by 256 is a myth. Sculpties have a range from -0.5 to +0.5 that maps to the 0 to 255 rgb ranges.
#11
Hi Domino, thanks for the enlightenment. I still had doubts because one can't put too much trust on a wiki, or any documentation for that matter. The evidence you presented removes any doubt, so I stand corrected.
I had the impression it improved due to the change I made but obviously it was something else I changed in the mesh, probably.
Dividing by 255 makes a lot more sense and it's much more useful so I'm glad the actual implementation diverges from the documentation in the wiki.
Thanks!
#12
No problem. I suspect you actually did see an improvement on your mesh. Sometimes little adjustments to the bake routine can seem to improve a model. It's not until you run a series of tests that it becomes clear you've improved one at the cost of making another worse.
When testing accuracy, I start with a single quad face, which I bake to a 64 x 64 image. Importing this map should give a 32 x 32 face sculptie with nice square faces. This tests the code enabled by checking the fill option. I then bake this sculptie and import again to make sure round tripping works. The 32 x 32 faces should align perfectly and this shows the edge draw and import routines are accurate. I then add a few levels of simple division and test again to prove that the reduction of high resolution meshes to sculptie size works.
Any problems with my other test sculpties then must be related to the calculation of the bounding box and scaling factors for the bake. I'm glad to say that there's no known problems with the baker in the latest 0.9.x releases, it's the most accurate and flexible sculptie baker I've written.
Post new comment