Forum Moderators: Staff
Poser Python Scripting F.A.Q (Last Updated: 2024 Mar 19 1:03 pm)
Another one regarding precision and rounding errors:
I move object files between Poser and Blender via network connection. I use struct for this to get the data as compact as possible (https://docs.python.org/3.7/library/struct.html).
For my buddy I wrote this explanation in the code:
FLOAT_FORMAT = "d" # Use double (8 byte) per floatingpoint number.
# You may use "f" instead of "d" and save half the
# memory requirement (using 4 bytes insteed of 8 per entry).
# But you may have to round the value, because of:
# VERT_PACK_FORMAT = "fff" # single floats
# a=struct.pack(VERT_PACK_FORMAT, 1.1, 2.1, 3.1)
# struct.unpack(VERT_PACK_FORMAT, a)
# >>> (1.100000023841858, 2.0999999046325684, 3.0999999046325684)
# --- vs ---
# VERT_PACK_FORMAT = "ddd" # double floats
# a=struct.pack(VERT_PACK_FORMAT, 1.1, 2.1, 3.1)
# struct.unpack(VERT_PACK_FORMAT, a)
# >>> (1.1, 2.1, 3.1)
#
# Using single precision may result in small differences
# if sending vertices back and forth.
PACK_FORMAT_VERT = FLOAT_FORMAT * 3 # 3 double floats
PACK_FORMAT_TVERT = FLOAT_FORMAT * 2 # 2 doubles floats
PACK_FORMAT_INT = "Q" # unsigned long long (8 bytes)
PACK_FORMAT_POLYGON = "QBBB" # unsigned long long (vert index), byte (numverts), byte (group), byte (mat)
PACK_FORMAT_TEXPOLYGON = "QB" # unsigned long long (vert index), byte (numverts)
BYTES_PER_VERT_ENTRY = struct.pack(PACK_FORMAT_VERT, 1.1, 2.1, 3.1).__len__()
BYTES_PER_TVERT_ENTRY = struct.pack(PACK_FORMAT_TVERT, 1.1, 2.1).__len__()
BYTES_PER_INT = struct.pack(PACK_FORMAT_INT, 1).__len__()
BYTES_PER_POLYGON = struct.pack(PACK_FORMAT_POLYGON, 0, 0, 0, 0, 0).__len__()
BYTES_PER_TEXPOLYGON = struct.pack(PACK_FORMAT_TEXPOLYGON, 0, 0).__len__()
This site uses cookies to deliver the best experience. Our own cookies make user accounts and other features possible. Third-party cookies are used to display relevant ads and to analyze how Renderosity is used. By using our site, you acknowledge that you have read and understood our Terms of Service, including our Cookie Policy and our Privacy Policy.
I made an interesting discovery when I exported a figure to Blender for morphing.
Up to now I assumed, that the values inside the OBJ file should be as large as possible and therefore exact. Because of this I always used 8 decimal places.
I just exported the figure to Blender this way (with my script), made a small change to the mesh in Blender, created a new OBJ from Blender that serves as a difference to the previous one. The result (the difference between the two files) should reflect the changes made and thus be a morph. So far so good. But: I got morphs for each actor. Although definitely only one actor was changed.
So I took a look at the OBJ file created by Blender - and was astonished: Blender uses only 6 decimal places!
After I changed my script to also use only 6 decimal places (when writing and reading), I got the desired result: Only one single actor got a morph assigned.
Since I had only used C4D for my thorough tests before, and C4D worked great with the 8 decimal places used, I never noticed that there was a problem.
I will test it further now and then adapt my scripts if necessary.
Translated with www.DeepL.com/Translator (free version)