1

this question is about blender, python scripting

I'm completely new in this, so please excuse me for any stupid/newbie question/comment.

I made it simple (3 lines code) to make it easy addressing the problem.

what I need is a code that adds a new uv map for each object within loop function.

But this code instead is adding multiple new UV maps to only one object.

import bpy
for x in bpy.context.selected_objects:
    bpy.ops.mesh.uv_texture_add()

what's wrong I'm doing here??

Thanks

  • I fixed the indent, but let me know if the indent was how you were executing it. – eandersson May 07 '16 at 11:43
  • yes @eandersson that's right, I've used to execute it like this, thank you, however, I don't really understand why does this make problem in the script editor :s, thanks for the edit :) – othman alazzam May 07 '16 at 11:46
  • 2
    You probably want to do some operation on `x`. I don't know Blender, so I can't suggest how to do whatever you want to do here. – Håken Lid May 07 '16 at 12:17
  • x is something that I don't know either, I've found this form of "loop" on web, which does work with others on their needs, but don't work with my need, this is what driving me mad – othman alazzam May 07 '16 at 12:48
  • 2
    Given a bag of apples, you do `for apple in bag: eat bag`. You probably want `for apple in bag: eat apple`. `x` - a random name - points to each of the objects in your object in turn, but you don't *do* anything with `x`. – Jongware May 07 '16 at 13:02
  • @martineau the problem isn't about python, it is specific to how blender works, the `bpy.ops.mesh.uv_texture_add()` is an operator that performs a task based on contextual data available within blender. The operator itself doesn't provide a way for you to tell it what object to work on (which we want to be x) so you need to adjust blender's context to make it work as wanted. Some operators work on selected objects others only the active object, while some need a specific editor to be active. This is a bit of a blender gotcha until you get used to how blender operators work. – sambler May 08 '16 at 03:04
  • @martineau I am a designer, and I wanted to write a little tool to help me speed up my workflow,,, why should I learn entire language in the time that I can build it from a little bit of a search on google and stackoverflow?!!!, I've actually built a long script for my need, but this is only small part of it where my problem was, I know it's pretty basic question, but the basic answer couldn't be found on google nor on stackoverflow, why can't I ask about it?,,, anyway, thanks for your feedback – othman alazzam May 08 '16 at 08:00

3 Answers3

2

Similar to what Sambler said, I always use:

for active in bpy.context.selected_objects:
    bpy.context.scene.objects.active = active
    ...

These two lines I use more than any other when programming for Blender (except import bpy of course).

I think I first learned this here if you'd like a good intro on how this works:

https://cgcookiemarkets.com/2014/12/11/writing-first-blender-script/

In the article he uses:

# Create a list of all the selected objects
selected = bpy.context.selected_objects

# Iterate through all selected objects
for obj in selected:
    bpy.context.scene.objects.active = obj
    ...

His comments explain it pretty well, but I will take it a step further. As you know, Blender lacks built-in multi-object editing, so you have selected objects and one active object. The active object is what you can and will edit if you try to set its values from python or Blender's gui itself. So although we are writing it slightly differently each time, the effect is the same. We loop over all selected objects with the for active in bpy.context.selected_objects, then we set the active object to be the next one in the loop that iterates over all the objects that are selected with bpy.context.scene.objects.active = active. As a result, whatever we do in the loop gets done once for every object in the selection and any operation we do on the object in question gets done on all of the objects. What would happen if we only used the first line and put our code in the for loop?

for active in bpy.context.selected_objects:
    ...

Whatever we do in the loop gets done once for every object in the selection but any operation we do on the object in question gets done on only the active object, but as many times as there are selected objects. This is why we need to set the active object from within the loop.

JakeD
  • 2,788
  • 2
  • 20
  • 29
0

note: I am not really familiar with blender

It seems that bpy.ops operations depend on the state of bpy.context. The context can also be overridden per-operation.

I assume that uv_texture_add() only works on a single object at a time?

Try something like this:

import bpy

for x in bpy.context.selected_objects:
    override = { "selected_objects": x }
    bpy.ops.mesh.uv_texture_add(override)

That should run the operations as if only one object was selected at a time.

Source:
https://www.blender.org/api/blender_python_api_2_63_17/bpy.ops.html#overriding-context

varesa
  • 2,399
  • 7
  • 26
  • 45
  • 1
    I appreciate your help brother, but unfortunately it did the same exact thing.... thanks for your help, I really appreciate it :) – othman alazzam May 07 '16 at 20:17
  • For override you would want to set the `active_object` not `selected_objects`. Unfortunately using override in this operator does not appear to work. – sambler May 08 '16 at 03:13
0

The uv_texture_add operator is one that only works on the current active object. You can change the active object by setting scene.objects.active

import bpy
for x in bpy.context.selected_objects:
    bpy.context.scene.objects.active = x
    bpy.ops.mesh.uv_texture_add()
sambler
  • 6,917
  • 1
  • 16
  • 23
  • that worked as a charm ^_^,, that's why I love stackoverflow, because of people like you ^_^ ,,, I knew that I have to change the active object but didn't know how, thank you very very very much bro, you saved the day :D – othman alazzam May 08 '16 at 07:57
  • sambler: This would be an even better answer if you also told the OP where you found out how blender operators work. – martineau May 08 '16 at 12:39