Reading lossy file format (PRC), resulting in precision problems

五迷三道 提交于 2019-12-10 15:42:56

问题


I got into making a viewer for various 3D file formats, and those formats that I had before didn't pose a problem, until I came to the PRC file (which is one of the supported 3D formats that can be embedded in PDFs). I can extract all the data from the PDF and display those models that were encoded in non-lossy ways, however when I tried to decode what they call "Highly Compressed Tesselations" I run into a problem that I think is a precision problem, but I don't quite know how to fix it or where to look for solutions.

Essentially it is a lossy format, and what they do is take the original (floating point based) vertex coordinates and -using a tolerance value- divide those coordinates by it and round the result to the nearest integer. When traversing the mesh to encode all the triangles, only the first triangle has absolute values stored, the remaining triangles are always based on a previous neighbouring triangle and building a local coordinate system with the middle of the shared edge being the origin, the vector along the shared edge being the x-axis, and the triangle normal being the z-axis. The y-axis is then just a result of the cross product of those, and using those 3 local axis it stores the coordinate for the third point of the new triangle.

I have the system generally working, and for simple models with not too many triangles it works well too, but as soon as the models get more complex the result goes all wrong, and it seems the further away from the last absolute coordinate, the bigger the deviation is.

In this example picture below you can see the expected result (as rendered in Adobe Reader) on the left, and mine on the right. This model essentially has an inner and an our section, and the inner section in this case is made of one absolute triangle followed by relative ones (whereas the outer section is made mostly from absolute coords, that's why it looks correct in mine), and the traversal going from the inner rings towards the outer ones. In the Adobe render you can see that the lines should be more or less radially pointing outward, whereas on mine, starting from about the fourth "circle" things start to go wrong:

Expected result on the left, my result on the right

I am currently stuck on this, and don't quite know how to solve this problem. I found that doing minor changes (such as changing double to float or vice versa) has a huge impact on the result, quickly making it much worse. But essentially I am following the spec, which says to use double precision floating point variables for all the calculations, and also to use their own implementation of calculating the square root (needed for normalizing the axis). For example by using their sqrt function instead of the one from the normal maths library, the result is already better (without that, I wouldn't even get near as close as in the pictures shown above).

But I was wondering if there is some kind of mathematical aspect that I am not grasping here? Or some other idea that might help? Also in that particular model the values all seem to be sufficiently big so that it should not be a problem of data loss due to lack of precision of the floating point format. Also there are special cases in the spec, where if the y- or z-axis are too short (< FLT_EPSILON) another solution has to be used, but again in this particular model the if < FLT_EPSILON case is never triggered.

Just FYI, here is the description about the encoding of the points (but there is no more info on particulars of decoding):

info from the PRC spec on how to encode points

Any input would be much appreciated. I can provide more data, info, examples, spec excerpts etc if needed.


回答1:


Based on my previous experiences with PRC, this looks very much like a problem with the object offset (I think it was called origin offset) being applied in the wrong place.

Due to the fact that each new vertex is based upon the previous one, using a local coordinate system based on the last triangle to get the third point of the new triangle, the errors seem to grow very, very quickly in this format, and being a lossy format doesn't help either. In my original approach I tried to calculate all the triangles, then apply the offset at the end to put it into the correct location, resulting in problems that look similar to yours.

By just changing it to apply the offset to "absolute vertices" (ie those that are read in unmodified, and sort of act as "anchor points" when a new triangle is started) I was able to fix the problem.

Of course, being PRC there are still various other things you might need to solve, where I am not sure whether you have already or not. A lot of things in the official ISO spec are just plain wrong, others not mentioned (for example when you are supposed to recalculate normals rather than getting explicit normals from the file), things like huffman compression have the bits wrong etc. If you can avoid it, then better not implement it ;-)



来源:https://stackoverflow.com/questions/36835984/reading-lossy-file-format-prc-resulting-in-precision-problems

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!