# How to mathematically round positions of all vertices to nearest integer?

I have a mesh with 1.5M vertices, and I'm trying to round off vertex positions to reduce the filesize of my exported .obj file. Each vertex has a very high level of precision, which I don't really need for this project. For example, I have a vertex at [492.98198, 382.19873, 274.98789], and would like to run a Python script to round it to [493, 382, 275], effectively reducing my output by over 50%!

Is there a python script that I could run to round off all 1.5M of my vertices in one go? This is as far as I've gone:

for vertex in bpy.data.meshes['meshname'].vertices:
vertex.co = round(vertex.co, 0)
vertex.co = round(vertex.co, 0)
vertex.co = round(vertex.co, 0)


But it seems like I can't really change the vertex values this way because mesh.vertices is a readonly attribute.

Anybody know how to modify the script so my vertices all snap to the nearest integer?

• Note that you are trying to edit mesh named "meshname". If you want to evaluate the variable it should be bpy.data.meshes[meshname] but can't really tell from this excerpt. The mesh.vertices is read-only which only means you can't assign a list of vertices to that variable. But it doesn't mean that all the data below would be uneditable and you should still be able to change vertex coords, layers data etc by accessing it like you are trying to. Oct 19, 2016 at 6:32
• Not sure about getting 50% reduction on export to obj, A vert at (1, 1, 1) will be exported to v 1.000000 1.000000 1.000000 in the obj file wont it? Running the rounding script over the obj file (or editing exporter to do so) would be more likely to help in this regard. Oct 19, 2016 at 15:04
• Further to above on line 233 (for example and in many other places) of io_scene_obj/export_obj.py 6 decimal places are hard coded in fw('v %.6f %.6f %.6f\n' % (ob_mat * pt.co.to_3d())[:]) to the output using a format string. You could do a global replace on %.6f to %.1f to have the format round the floats to 1 decimal place. Oct 19, 2016 at 15:25
• @batFINGER you are correct. I did notice that the .obj file still retained a high level of precision on each vertex. Being a python newbie, I just opened it in a text editor and manually deleted all instances of .000000
– M -
Oct 19, 2016 at 16:45
• That'll do it 8^) Oct 19, 2016 at 16:47

Use the following script:

import bpy

obj = bpy.context.scene.objects.active

for vert in obj.data.vertices:
vert.co.x = round(vert.co.x)
vert.co.y = round(vert.co.y)
vert.co.z = round(vert.co.z)


Let me know if you run into any problems :-)

• Fantastic! Thanks. What was I really changing on my attempt, when accessing bpy.data.meshes['meshname']? Was it something stored in memory?
– M -
Oct 18, 2016 at 22:27
• I just ran what you had and it should work ok, if there really is a mesh named "meshname". Note that this is not an object but a mesh. The way I wrote it is much more robust though as it works on the active object and it is cleaner in the way that it rounds the number. Oct 19, 2016 at 0:15
• Hi! do you have something that works for blender 3.5 and up? Thank you. Jun 4 at 13:11

Why don't you simply use loop?

for verticle in bpy.data.meshes['meshname'].verticles:
verticle = int(round(verticle))


Will this work for you?

• Not entirely. It does help me loop through all the vertices, which is nice. But now I need to figure out how to round each value. For example vertex.x = round(vertex.x, 0) but I get an error saying that MeshVertex object does not have attribute 'X'... so I have to figure out how to access each vertex's attributes.
– M -
Oct 18, 2016 at 21:03
• This will not work at all. What do you expect a vertex (or verticle as you say) to round to? Oct 18, 2016 at 22:25