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$
    – Chgad
    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.

Not the answer you're looking for? Browse other questions tagged .