2
$\begingroup$

I'm completly new to Blender. I currently work on a project which could utilize Blender for Beveling. To get in touch with blender I first played around with the programm itself and then tried to implement it into a Python script.

My goal/way to go is the Following:

  1. Create Meshes/Objects from my custom Code.
  2. Add different Materials to them
  3. Select all
  4. Join all Objects
  5. Bevel by applying a Bevel Modifier
  6. Seperate them by Material

Since I'm still in the "playground" phase with Blender i started with a simple one by one Cube as seen in the following Code:

import bpy

vertices = [
    (0.0, 0.0, 0.0),  # 0
    (1.0, 0.0, 0.0),  # 1
    (0.0, 1.0, 0.0),  # 2
    (0.0, 0.0, 1.0),  # 3
    (1.0, 1.0, 1.0),  # 4
    (1.0, 1.0, 0.0),  # 5
    (1.0, 0.0, 1.0),  # 6
    (0.0, 1.0, 1.0),  # 7
]

faces = [
    (0, 1, 6, 3),  # Frontface
    (2, 7, 4, 5),  # Backface
    (0, 3, 7, 2),  # Leftface
    (1, 5, 4, 6),  # Rightface
    (0, 2, 5, 1),  # Bottomface
    (3, 6, 4, 7),  # Topface
]

vertices_two = [
    (0.0, 0.0, 1.0),  # 0 (3)
    (1.0, 1.0, 1.0),  # 1 (4)
    (1.0, 0.0, 1.0),  # 2 (6)
    (0.0, 1.0, 1.0),  # 3 (7)
]

faces_two = [(0, 2, 1, 3)]


mesh_data = bpy.data.meshes.new("test_cube_half")
mesh_data.from_pydata(vertices, [], faces[:-1])

obj = bpy.data.objects.new("Half_Cube", mesh_data)
mat = bpy.data.materials.new(name="Test_Material_one")
obj.data.materials.append(mat)
bpy.context.collection.objects.link(obj)


mesh_data_two = bpy.data.meshes.new("Test_top_face")
mesh_data_two.from_pydata(vertices_two, [], faces_two)

obj_two = bpy.data.objects.new("My_object_two", mesh_data_two)
mat_two = bpy.data.materials.new(name="Test_Material_two")
obj_two.data.materials.append(mat_two)

bpy.context.collection.objects.link(obj_two)

bpy.ops.object.select_all(action='SELECT')

bpy.ops.object.join()

With this Code I create an Object which is the Cube WITHOUT the top face and an Object which is the missing Top face.

I execute this script via blender --python my_script.py.

The provided Code works until the last line, there it fails with the following Error :

RuntimeError: Operator bpy.ops.object.join.poll() failed, context is incorrect

So now I have two Question :

  1. Is the mentioned workflow of mine even possible with a script ?
  2. What IS the correct context for join() and how do I set it ?

NOTE:

  1. bpy is build for Python 3.6 (if anyone needs this info).
  2. If i try the solution of This Question i get the following error:

    AttributeError: bpy_prop_collection: attribute "active" not found

  3. This Questions Answer does not work either and gives an AttributeError for select for each Object.

Thanks in adnvance.

$\endgroup$
1

2 Answers 2

2
$\begingroup$

Need an active object

The join operator joins all selected mesh (or same type join-able) objects to active object. As proposed in link 2

How to join objects with Python?

in 2.79 you set an object to active in scene with scene.objects.active = obj whereas in 2.80 use the context.view_layer.objects.active = obj to make an object active.

Add this line before the operator and should work as expected.

bpy.context.view_layer.objects.active = obj
bpy.ops.object.join()
$\endgroup$
1
  • $\begingroup$ Thank you very much. Is there any source where i can read more about that ? $\endgroup$ Commented Jan 10, 2019 at 16:52
0
$\begingroup$

Inspired from the above solution, here is a complete code for joining a collection of objects

meshes = [mesh for mesh in assetCollection.all_objects if mesh.type == 'MESH']
for mesh in meshes:
    mesh.select_set(state=True)
    bpy.context.view_layer.objects.active = mesh
bpy.ops.object.join()

obj = assetCollection.all_objects[0]
```
$\endgroup$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.