2

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.

Chgad
  • 255
  • 3
  • 10
  • 1
    https://blender.stackexchange.com/questions/6101/poll-failed-context-incorrect-example-bpy-ops-view3d-background-image-add This may be useful – Tim Jan 09 '19 at 20:42

2 Answers2

2

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()
batFINGER
  • 84,216
  • 10
  • 108
  • 233
0

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] ```

prerakmody
  • 31
  • 2