I'm trying to run the remove_doubles edit command on multiple selected objects. This is kinda what I got so far...

import bpy

class remDoubles(bpy.types.Operator):
    """Remove Doubles on multiple objects"""
    bl_label = "Remove Multiple Doubles"
    bl_idname = "object.remove_doubles_multi"
    bl_options = {'REGISTER', 'UNDO'}

    def poll(cls, context):
        return len(context.selected_objects) > 0

    def execute(self, context):

        scene = bpy.context.scene
        sel = context.selected_objects

        for obj in sel:
            scene.objects.active = obj

            #do something here

        return {"FINISHED"}

myobject = remDoubles()


My knowledge about classes isn't too great, please help.

My code needs some work, it just errors out giving a 'TypeError: bpy_struct.new(type): expected a single argument'

But what i intend doing is run through each object applying the remove doubles command for each.

  • $\begingroup$ What are you asking? What happens instead of removing doubles from multiple objects when you run the code? $\endgroup$ – 10 Replies Nov 27 '16 at 20:02
  • $\begingroup$ My code needs some work, it just errors out giving a 'TypeError: bpy_struct.__new__(type): expected a single argument' But what i intend doing is run through each object applying the remove doubles command for each. $\endgroup$ – Dillz Sinden Nov 27 '16 at 20:06
  • $\begingroup$ Include this information in your question. It is unclear what you are asking for without it. $\endgroup$ – 10 Replies Nov 27 '16 at 20:07

Firstly operators don't work in a usual create class instance way... the code below

myobject = remDoubles()

Will NOT work.

Have a look at the Hello World Example The HelloWorldOperatoroperator class is defined, registered (known to bpy.ops), then called using bpy.ops. "plus" the bl_idname.

In your example you would

bpy.utils.register_class(RemoveDoublesMulti) # changed to camel-case name

# test call to the newly defined operator

Using a bmesh approach avoids toggling in and out of edit mode, changing the context object ... etc. An alternative for execute:

import bpy
import bmesh

context = bpy.context

distance = 0.0 # remove doubles tolerance.
if True: #def execute(self, context):

    meshes = set(o.data for o in context.selected_objects
                      if o.type == 'MESH')

    bm = bmesh.new()

    for m in meshes:
        bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=distance)

  • $\begingroup$ Thanks for clearing things up by explaining that the operators don't work as normal class instances. I will look into the example. The bmesh method really captivated me though as it is sooo fast so I'd do a little bit more research on that. BTW i did have to change the distance = distance to dist = distance. $\endgroup$ – Dillz Sinden Nov 28 '16 at 20:40
  • $\begingroup$ Fixed, thankyou. If you want to make a report sum(len(m.vertices) for m in meshes) will give you the total verts in all selected meshes. The difference in result when run before and after operator loop, gives total removed verts. $\endgroup$ – batFINGER Nov 29 '16 at 11:00
  • $\begingroup$ using the set() is to avoid running it again on instances of the same mesh used by other objects if I am not mistaken? Very clever! $\endgroup$ – aliasguru Jul 18 '19 at 8:26

Below is a simple script that will loop on the meshes you have in your scene and remove doubles from only the MESH objects.

import bpy

if bpy.context.selected_objects != []:
    for obj in bpy.context.selected_objects:
        if obj.type == 'MESH':
            bpy.context.scene.objects.active = obj
  • 2
    $\begingroup$ Thank you so much for this. Though the bmesh method gets executed waaay faster, this has given me new insight for quickly running edit mode commands over multiple meshes. $\endgroup$ – Dillz Sinden Nov 28 '16 at 20:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.